From dd6c9d4aa733d518915a9c6af509cabf42eed093 Mon Sep 17 00:00:00 2001 From: sefgsefg Date: Fri, 21 Jun 2024 19:54:17 +0800 Subject: [PATCH] add RAG pipeline with nodered example Signed-off-by: sefgsefg --- .../LICENSE | 1348 +- .../README.md | 136 +- .../vgg16.ipynb | 2016 +- Facial-Keypoint-Detection/Readme.md | 86 +- .../generate-pipeline/my_pipeline.py | 84 +- .../g-research-crypto-forecast-kale.ipynb | 2048 +- .../g-research-crypto-forecast-kfp.ipynb | 1620 +- .../g-research-crypto-forecast-orig.ipynb | 2026 +- .../2. Docker/static/styles.css | 178 +- .../2. Docker/templates/home.html | 312 +- .../RAG_with_node-red/FL_pipeline.png | Bin 0 -> 12001 bytes .../RAG_with_node-red/build_flow.png | Bin 0 -> 5953 bytes .../RAG_with_node-red/edit_node.png | Bin 0 -> 7638 bytes .../RAG_with_node-red/example/Dockerfile | 24 + .../RAG_with_node-red/example/build.sh | 3 + .../buckets/.bloomcycle.bin/xl.meta | Bin 0 -> 741 bytes .../.minio.sys/buckets/.usage.json/xl.meta | Bin 0 -> 634 bytes .../.minio.sys/config/config.json/xl.meta | Bin 0 -> 9484 bytes .../.minio.sys/config/iam/format.json/xl.meta | Bin 0 -> 434 bytes .../example/data/.minio.sys/format.json | 1 + .../example/data/.minio.sys/pool.bin/xl.meta | Bin 0 -> 479 bytes .../xl.meta.bkp | Bin 0 -> 634 bytes .../xl.meta.bkp | Bin 0 -> 741 bytes .../xl.meta.bkp | Bin 0 -> 634 bytes .../xl.meta.bkp | Bin 0 -> 634 bytes .../xl.meta.bkp | Bin 0 -> 741 bytes .../xl.meta.bkp | Bin 0 -> 741 bytes .../tmp/3539f56f-7c06-4b3f-9136-987f1f337bea | Bin 0 -> 2049 bytes .../example/docker-compose.yaml | 43 + .../example/main/.config.nodes.json | 446 + .../example/main/.config.users.json | 20 + .../example/main/.config.users.json.backup | 17 + .../example/main/.flows.json.backup | 650 + .../RAG_with_node-red/example/main/flows.json | 697 + .../example/main/flows_cred.json | 3 + .../node_modules/autoAI pipeline/RAG/RAG.html | 91 + .../node_modules/autoAI pipeline/RAG/RAG.js | 120 + .../node_modules/autoAI pipeline/package.json | 19 + .../node_modules/autoAI pipeline/snippets.js | 342 + .../example/main/package.json | 6 + .../RAG_with_node-red/example/main/py/RAG.py | 0 .../main/py/api_examples/create_experiment.py | 59 + .../main/py/api_examples/create_run.py | 58 + .../main/py/api_examples/delete_experiment.py | 51 + .../main/py/api_examples/delete_pipeline.py | 50 + .../main/py/api_examples/delete_run.py | 50 + .../example/main/py/api_examples/get_run.py | 64 + .../example/main/py/api_examples/kfp_login.py | 93 + .../main/py/api_examples/kfp_namespace.py | 19 + .../main/py/api_examples/list_experiments.py | 44 + .../main/py/api_examples/list_pipelines.py | 43 + .../main/py/api_examples/upload_pipeline.py | 52 + .../example/main/py/deploykserve.py | 205 + .../example/main/py/examples/kfp_login.py | 93 + .../example/main/py/examples/kfp_namespace.py | 19 + .../example/main/py/install.py | 27 + .../example/main/py/kfp_login.py | 93 + .../example/main/py/kfp_namespace.py | 19 + .../pipelines_yamls/only_decision_tree.yaml | 131 + .../only_logistic_regression.yaml | 131 + .../py/pipelines_yamls/only_randomforest.yaml | 131 + .../py/pipelines_yamls/three-pipeline.yaml | 229 + .../example/main/py/requirements.txt | 4 + .../example/main/py/sklearn-kserve.yaml | 184 + .../example/main/settings.js | 498 + .../example/package-lock.json | 10782 +++ .../RAG_with_node-red/example/package.json | 127 + .../RAG_with_node-red/example/run.sh | 14 + .../example/scripts/entrypoint.sh | 14 + .../RAG_with_node-red/example/test | 0 RAG-pipeline-with-nodered/README.md | 48 + RAG-pipeline-with-nodered/node-red_1.png | Bin 0 -> 32998 bytes RAG-pipeline-with-nodered/node-red_2.png | Bin 0 -> 33070 bytes RAG-pipeline-with-nodered/pipeline.png | Bin 0 -> 12988 bytes ...ican-express-default-prediction-kale.ipynb | 1542 +- ...rican-express-default-prediction-kfp.ipynb | 1558 +- ...ican-express-default-prediction-orig.ipynb | 1744 +- .../requirements.txt | 14 +- .../Readme.md | 696 +- ...k-for-bulldozers-kaggle-competition-kfp.py | 124 +- .../ks/launch_search_index_creator_job.sh | 0 .../docker/ks/submit_code_embeddings_job.sh | 0 code_search/docker/ks/update_index.sh | 0 code_search/docker/t2t/t2t-entrypoint.sh | 0 code_search/docker/ui/build.sh | 0 .../kubeflow/environments/base.libsonnet | 4 - .../environments/cs_demo/globals.libsonnet | 9 - .../environments/cs_demo/main.jsonnet | 8 - .../environments/cs_demo/params.libsonnet | 22 - .../environments/pipeline/globals.libsonnet | 7 - .../environments/pipeline/main.jsonnet | 8 - .../environments/pipeline/params.libsonnet | 12 - .../nmslib/cli/start_test_server.sh | 0 codes/volume_parallel.py | 122 +- demos/simple_pipeline/gpu-example-pipeline.py | 0 demos/yelp_demo/demo_setup/create_context.sh | 0 .../pipelines/gpu-example-pipeline.py | 0 .../yelp/yelp_sentiment/worker_launcher.sh | 0 .../data/sample_submission.csv | 56002 ++++++++-------- .../requirements.txt | 8 +- .../Readme.md | 396 +- .../facial-keypoints-detection-kfp.py | 90 +- github_issue_summarization/Makefile | 0 .../containers/tf-serving-gh/build.sh | 0 .../components/t2t/containers/base/build.sh | 0 .../t2t/containers/metadata-logger/build.sh | 0 .../t2t/containers/t2t_app/build.sh | 0 .../t2t/containers/t2t_proc/build.sh | 0 .../t2t/containers/t2t_train/build.sh | 0 .../t2t/containers/webapp-launcher/build.sh | 0 h-and-m-fash-rec-kaggle-competition/README.md | 358 +- .../helper-files/local_api.py | 186 +- mnist/Makefile | 0 .../components/build_components.sh | 0 .../components/copy_specification.sh | 0 .../components/deploy/build_image.sh | 0 .../components/preprocess/build_image.sh | 0 .../components/train/build_image.sh | 0 .../routine/build_routine.sh | 0 .../requirements.txt | 14 +- .../ks-app/environments/base.libsonnet | 4 - openvaccine-kaggle-competition/Readme.md | 756 +- .../openvaccine-kaggle-competition-kfp.py | 162 +- pipelines-demo/volume/volume_example.py | 124 +- .../azurepipeline/code/deploy/Dockerfile | 0 pipelines/azurepipeline/code/deploy/score.py | 0 .../azurepipeline/code/preprocess/Dockerfile | 0 .../azurepipeline/code/preprocess/data.py | 0 .../azurepipeline/code/register/Dockerfile | 0 .../azurepipeline/code/register/register.py | 0 .../azurepipeline/code/training/Dockerfile | 0 .../azurepipeline/code/training/train.py | 0 .../deploy-service/src/deploy.sh | 0 pipelines/simple-notebook-pipeline/README.md | 20 +- pytorch_mnist/Makefile | 0 .../serving/seldon-wrapper/build_image.sh | 0 .../training/ddp/mnist/Dockerfile.traingpu | 0 .../training/ddp/mnist/build_image.sh | 0 pytorch_mnist/training/ddp/mnist/mnist_DDP.py | 0 pytorch_mnist/web-ui/build_image.sh | 0 .../images/... | 1 - .../requirements.txt | 12 +- .../distributed_text_classification_rnn.py | 0 test/copy_secret.sh | 0 titanic-kaggle-competition/Readme.md | 928 +- 145 files changed, 53169 insertions(+), 37430 deletions(-) create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/FL_pipeline.png create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/build_flow.png create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/edit_node.png create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/Dockerfile create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/build.sh create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/buckets/.bloomcycle.bin/xl.meta create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/buckets/.usage.json/xl.meta create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/config/config.json/xl.meta create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/config/iam/format.json/xl.meta create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/format.json create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/pool.bin/xl.meta create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/7a4afe59-3ebb-451e-8f3e-2aa2972ace33/xl.meta.bkp create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/9fb77816-7f6e-40e0-8b08-f7ca83d930d1/xl.meta.bkp create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/a4349609-22f1-4a1f-b126-76ba138ed9ed/xl.meta.bkp create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/e1bb8ce0-0f21-4822-b751-7787775fcd26/xl.meta.bkp create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/eb32cdeb-d251-4717-bcd7-d215b85af238/xl.meta.bkp create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/f5502d0b-3d43-4bfc-8cf8-cef3f051a433/xl.meta.bkp create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/3539f56f-7c06-4b3f-9136-987f1f337bea create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/docker-compose.yaml create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/.config.nodes.json create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/.config.users.json create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/.config.users.json.backup create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/.flows.json.backup create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/flows.json create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/flows_cred.json create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/node_modules/autoAI pipeline/RAG/RAG.html create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/node_modules/autoAI pipeline/RAG/RAG.js create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/node_modules/autoAI pipeline/package.json create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/node_modules/autoAI pipeline/snippets.js create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/package.json create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/RAG.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/api_examples/create_experiment.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/api_examples/create_run.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/api_examples/delete_experiment.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/api_examples/delete_pipeline.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/api_examples/delete_run.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/api_examples/get_run.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/api_examples/kfp_login.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/api_examples/kfp_namespace.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/api_examples/list_experiments.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/api_examples/list_pipelines.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/api_examples/upload_pipeline.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/deploykserve.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/examples/kfp_login.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/examples/kfp_namespace.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/install.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/kfp_login.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/kfp_namespace.py create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/pipelines_yamls/only_decision_tree.yaml create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/pipelines_yamls/only_logistic_regression.yaml create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/pipelines_yamls/only_randomforest.yaml create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/pipelines_yamls/three-pipeline.yaml create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/requirements.txt create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/py/sklearn-kserve.yaml create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/main/settings.js create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/package-lock.json create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/package.json create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/run.sh create mode 100644 RAG-pipeline-with-nodered/RAG_with_node-red/example/scripts/entrypoint.sh rename jpx-tokyo-stock-exchange-kaggle-competition/images/... => RAG-pipeline-with-nodered/RAG_with_node-red/example/test (100%) create mode 100644 RAG-pipeline-with-nodered/README.md create mode 100644 RAG-pipeline-with-nodered/node-red_1.png create mode 100644 RAG-pipeline-with-nodered/node-red_2.png create mode 100644 RAG-pipeline-with-nodered/pipeline.png mode change 100755 => 100644 code_search/docker/ks/launch_search_index_creator_job.sh mode change 100755 => 100644 code_search/docker/ks/submit_code_embeddings_job.sh mode change 100755 => 100644 code_search/docker/ks/update_index.sh mode change 100755 => 100644 code_search/docker/t2t/t2t-entrypoint.sh mode change 100755 => 100644 code_search/docker/ui/build.sh delete mode 100644 code_search/kubeflow/environments/base.libsonnet delete mode 100644 code_search/kubeflow/environments/cs_demo/globals.libsonnet delete mode 100644 code_search/kubeflow/environments/cs_demo/main.jsonnet delete mode 100644 code_search/kubeflow/environments/cs_demo/params.libsonnet delete mode 100644 code_search/kubeflow/environments/pipeline/globals.libsonnet delete mode 100644 code_search/kubeflow/environments/pipeline/main.jsonnet delete mode 100644 code_search/kubeflow/environments/pipeline/params.libsonnet mode change 100755 => 100644 code_search/src/code_search/nmslib/cli/start_test_server.sh mode change 100755 => 100644 demos/simple_pipeline/gpu-example-pipeline.py mode change 100755 => 100644 demos/yelp_demo/demo_setup/create_context.sh mode change 100755 => 100644 demos/yelp_demo/pipelines/gpu-example-pipeline.py mode change 100755 => 100644 demos/yelp_demo/yelp/yelp_sentiment/worker_launcher.sh mode change 100755 => 100644 github_issue_summarization/Makefile mode change 100755 => 100644 github_issue_summarization/pipelines/components/kubeflow-resources/containers/tf-serving-gh/build.sh mode change 100755 => 100644 github_issue_summarization/pipelines/components/t2t/containers/base/build.sh mode change 100755 => 100644 github_issue_summarization/pipelines/components/t2t/containers/metadata-logger/build.sh mode change 100755 => 100644 github_issue_summarization/pipelines/components/t2t/containers/t2t_app/build.sh mode change 100755 => 100644 github_issue_summarization/pipelines/components/t2t/containers/t2t_proc/build.sh mode change 100755 => 100644 github_issue_summarization/pipelines/components/t2t/containers/t2t_train/build.sh mode change 100755 => 100644 github_issue_summarization/pipelines/components/t2t/containers/webapp-launcher/build.sh mode change 100755 => 100644 mnist/Makefile mode change 100755 => 100644 named_entity_recognition/components/build_components.sh mode change 100755 => 100644 named_entity_recognition/components/copy_specification.sh mode change 100755 => 100644 named_entity_recognition/components/deploy/build_image.sh mode change 100755 => 100644 named_entity_recognition/components/preprocess/build_image.sh mode change 100755 => 100644 named_entity_recognition/components/train/build_image.sh mode change 100755 => 100644 named_entity_recognition/routine/build_routine.sh delete mode 100644 object_detection/ks-app/environments/base.libsonnet mode change 100755 => 100644 pipelines/azurepipeline/code/deploy/Dockerfile mode change 100755 => 100644 pipelines/azurepipeline/code/deploy/score.py mode change 100755 => 100644 pipelines/azurepipeline/code/preprocess/Dockerfile mode change 100755 => 100644 pipelines/azurepipeline/code/preprocess/data.py mode change 100755 => 100644 pipelines/azurepipeline/code/register/Dockerfile mode change 100755 => 100644 pipelines/azurepipeline/code/register/register.py mode change 100755 => 100644 pipelines/azurepipeline/code/training/Dockerfile mode change 100755 => 100644 pipelines/azurepipeline/code/training/train.py mode change 100755 => 100644 pipelines/mnist-pipelines/deploy-service/src/deploy.sh mode change 100755 => 100644 pytorch_mnist/Makefile mode change 100755 => 100644 pytorch_mnist/serving/seldon-wrapper/build_image.sh mode change 100755 => 100644 pytorch_mnist/training/ddp/mnist/Dockerfile.traingpu mode change 100755 => 100644 pytorch_mnist/training/ddp/mnist/build_image.sh mode change 100755 => 100644 pytorch_mnist/training/ddp/mnist/mnist_DDP.py mode change 100755 => 100644 pytorch_mnist/web-ui/build_image.sh delete mode 100644 telco-customer-churn-kaggle-competition/images/... mode change 100755 => 100644 tensorflow_cuj/text_classification/distributed_text_classification_rnn.py mode change 100755 => 100644 test/copy_secret.sh diff --git a/Chinese-multiperson-voice-recognition-transfer-learning/LICENSE b/Chinese-multiperson-voice-recognition-transfer-learning/LICENSE index 3877ae0a7..f288702d2 100644 --- a/Chinese-multiperson-voice-recognition-transfer-learning/LICENSE +++ b/Chinese-multiperson-voice-recognition-transfer-learning/LICENSE @@ -1,674 +1,674 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Chinese-multiperson-voice-recognition-transfer-learning/README.md b/Chinese-multiperson-voice-recognition-transfer-learning/README.md index 6719e5c66..d2e5fa00f 100644 --- a/Chinese-multiperson-voice-recognition-transfer-learning/README.md +++ b/Chinese-multiperson-voice-recognition-transfer-learning/README.md @@ -1,68 +1,68 @@ -# Chinese-multiperson-voice-recognition-using-transfer-learning -This is an example of applying transfer learning to the Chinese multi-person voice recognition application. Transfer learning is an AI technique used to enhance the training accuracy of use cases when the dataset is small or the training accuracy is low given the high noise of the original dataset. Multi-person voice recognition is known to contain high noise in the dataset. Chinese voice voice recognition has gained much progress recently thanks to the effort by the big name company such as Google. However many issues remain unsolved. Multi-person Chinese voice recognition is one of them. This example provieds not only multi-person Chinese voice sample dataset, but applied a transfer learning technique to the CNN trained model of the Chinese voice samples dataset. Satisfactory results can be achieved through transfer learning after an initial CNN training. -This example provides a feasibility evidence of the transfer learning techniques, and it is our wish to convert the transfer learning technique to a Kubeflow asset through this illustration case. A transfer learning pipeline will be constructed to make kubeflow user easy to adapt to their model for training accuracy enhancement. Eventually, other users can benefit from such convenient features of the kubeflow resources. - -usage briefing: -1.Process audio files and convert them into spectrograms. -2.Establish experimental data, divide them into 3 categories, and set them into CNN network training. -3.Perform two training sessions to improve accuracy. -4.Compare training methods. - -Tools used: -1. TensorFlow -2. Anaconda -3. Python3.7 - -1. preprocess(spectrograms production) - -![image](https://user-images.githubusercontent.com/58965086/122675714-48a34700-d20d-11eb-81d7-865209ac8367.png) - -2. import spectrogram files. -![image](https://user-images.githubusercontent.com/58965086/122675748-712b4100-d20d-11eb-96cd-1523b9329020.png) - -![image](https://user-images.githubusercontent.com/58965086/122675762-8011f380-d20d-11eb-90db-f7b8942571d5.png) - -3. build training dataset: -divide the dataset into training, validation, and testing sets. - -![image](https://user-images.githubusercontent.com/58965086/122675818-b8b1cd00-d20d-11eb-836a-08fa3e870823.png) - -4. build CNN taining: - -![image](https://user-images.githubusercontent.com/58965086/122675838-d54e0500-d20d-11eb-8076-8dc78600a779.png) - -5. first training -![image](https://user-images.githubusercontent.com/58965086/122675851-e565e480-d20d-11eb-8ad4-4dada12f70a0.png) -![image](https://user-images.githubusercontent.com/58965086/122675854-ea2a9880-d20d-11eb-82f8-4ad9fc506386.png) - -6. first training result: -![image](https://user-images.githubusercontent.com/58965086/122675877-03cbe000-d20e-11eb-8f64-1c4ad9cec5a8.png) - -7. visualize the result -![image](https://user-images.githubusercontent.com/58965086/122675890-1b0acd80-d20e-11eb-84da-1793cac58fe2.png) - -![image](https://user-images.githubusercontent.com/58965086/122675896-2100ae80-d20e-11eb-8901-240b7d9b3566.png) - -8. import VGG16 model -![image](https://user-images.githubusercontent.com/58965086/122675911-37a70580-d20e-11eb-95ab-a4a652fa79ab.png) -![image](https://user-images.githubusercontent.com/58965086/122675916-3e357d00-d20e-11eb-99ab-a5d22facba9c.png) - -9. use conv_base model to extract features and labels -![image](https://user-images.githubusercontent.com/58965086/122675969-7937b080-d20e-11eb-885d-c5f202b3457a.png) - -10. training -![image](https://user-images.githubusercontent.com/58965086/122676010-92d8f800-d20e-11eb-8826-5b599bc78b4b.png) - -11. visualize the results -![image](https://user-images.githubusercontent.com/58965086/122676032-a71cf500-d20e-11eb-82fc-a2a468340a53.png) - -12. build confusion matrix -![image](https://user-images.githubusercontent.com/58965086/122676055-c1ef6980-d20e-11eb-81af-c394696124c7.png) - -13. visualiz the confusion matrix -![image](https://user-images.githubusercontent.com/58965086/122676069-d7fd2a00-d20e-11eb-8dcb-064f8406e9a4.png) - -14. sample Chinese multiperson voice spectrogram files are added -15. sample VGG16 transfer learning code: vgg16.ipynb is added to the repository - - +# Chinese-multiperson-voice-recognition-using-transfer-learning +This is an example of applying transfer learning to the Chinese multi-person voice recognition application. Transfer learning is an AI technique used to enhance the training accuracy of use cases when the dataset is small or the training accuracy is low given the high noise of the original dataset. Multi-person voice recognition is known to contain high noise in the dataset. Chinese voice voice recognition has gained much progress recently thanks to the effort by the big name company such as Google. However many issues remain unsolved. Multi-person Chinese voice recognition is one of them. This example provieds not only multi-person Chinese voice sample dataset, but applied a transfer learning technique to the CNN trained model of the Chinese voice samples dataset. Satisfactory results can be achieved through transfer learning after an initial CNN training. +This example provides a feasibility evidence of the transfer learning techniques, and it is our wish to convert the transfer learning technique to a Kubeflow asset through this illustration case. A transfer learning pipeline will be constructed to make kubeflow user easy to adapt to their model for training accuracy enhancement. Eventually, other users can benefit from such convenient features of the kubeflow resources. + +usage briefing: +1.Process audio files and convert them into spectrograms. +2.Establish experimental data, divide them into 3 categories, and set them into CNN network training. +3.Perform two training sessions to improve accuracy. +4.Compare training methods. + +Tools used: +1. TensorFlow +2. Anaconda +3. Python3.7 + +1. preprocess(spectrograms production) + +![image](https://user-images.githubusercontent.com/58965086/122675714-48a34700-d20d-11eb-81d7-865209ac8367.png) + +2. import spectrogram files. +![image](https://user-images.githubusercontent.com/58965086/122675748-712b4100-d20d-11eb-96cd-1523b9329020.png) + +![image](https://user-images.githubusercontent.com/58965086/122675762-8011f380-d20d-11eb-90db-f7b8942571d5.png) + +3. build training dataset: +divide the dataset into training, validation, and testing sets. + +![image](https://user-images.githubusercontent.com/58965086/122675818-b8b1cd00-d20d-11eb-836a-08fa3e870823.png) + +4. build CNN taining: + +![image](https://user-images.githubusercontent.com/58965086/122675838-d54e0500-d20d-11eb-8076-8dc78600a779.png) + +5. first training +![image](https://user-images.githubusercontent.com/58965086/122675851-e565e480-d20d-11eb-8ad4-4dada12f70a0.png) +![image](https://user-images.githubusercontent.com/58965086/122675854-ea2a9880-d20d-11eb-82f8-4ad9fc506386.png) + +6. first training result: +![image](https://user-images.githubusercontent.com/58965086/122675877-03cbe000-d20e-11eb-8f64-1c4ad9cec5a8.png) + +7. visualize the result +![image](https://user-images.githubusercontent.com/58965086/122675890-1b0acd80-d20e-11eb-84da-1793cac58fe2.png) + +![image](https://user-images.githubusercontent.com/58965086/122675896-2100ae80-d20e-11eb-8901-240b7d9b3566.png) + +8. import VGG16 model +![image](https://user-images.githubusercontent.com/58965086/122675911-37a70580-d20e-11eb-95ab-a4a652fa79ab.png) +![image](https://user-images.githubusercontent.com/58965086/122675916-3e357d00-d20e-11eb-99ab-a5d22facba9c.png) + +9. use conv_base model to extract features and labels +![image](https://user-images.githubusercontent.com/58965086/122675969-7937b080-d20e-11eb-885d-c5f202b3457a.png) + +10. training +![image](https://user-images.githubusercontent.com/58965086/122676010-92d8f800-d20e-11eb-8826-5b599bc78b4b.png) + +11. visualize the results +![image](https://user-images.githubusercontent.com/58965086/122676032-a71cf500-d20e-11eb-82fc-a2a468340a53.png) + +12. build confusion matrix +![image](https://user-images.githubusercontent.com/58965086/122676055-c1ef6980-d20e-11eb-81af-c394696124c7.png) + +13. visualiz the confusion matrix +![image](https://user-images.githubusercontent.com/58965086/122676069-d7fd2a00-d20e-11eb-8dcb-064f8406e9a4.png) + +14. sample Chinese multiperson voice spectrogram files are added +15. sample VGG16 transfer learning code: vgg16.ipynb is added to the repository + + diff --git a/Chinese-multiperson-voice-recognition-transfer-learning/vgg16.ipynb b/Chinese-multiperson-voice-recognition-transfer-learning/vgg16.ipynb index 86652b0a9..b87ba944c 100644 --- a/Chinese-multiperson-voice-recognition-transfer-learning/vgg16.ipynb +++ b/Chinese-multiperson-voice-recognition-transfer-learning/vgg16.ipynb @@ -1,1008 +1,1008 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "#匯入訓練、驗證、測試圖像\n", - "import os,shutil\n", - "\n", - "base_dir = 'Rec'\n", - "if not os.path.isdir(base_dir):\n", - " os.mkdir(base_dir)\n", - " \n", - "train_dir = os.path.join(base_dir, 'train')\n", - "os.mkdir(train_dir)\n", - "validation_dir = os.path.join(base_dir, 'validation')\n", - "os.mkdir(validation_dir)\n", - "test_dir = os.path.join(base_dir, 'test')\n", - "os.mkdir(test_dir)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "#建立訓練集資料夾\n", - "train_b_dir = os.path.join(train_dir, 'be')\n", - "os.mkdir(train_b_dir)\n", - "\n", - "train_h_dir = os.path.join(train_dir, 'ho')\n", - "os.mkdir(train_h_dir)\n", - "\n", - "\n", - "train_y_dir = os.path.join(train_dir, 'yun')\n", - "os.mkdir(train_y_dir)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "#建立驗證集資料夾\n", - "validation_b_dir = os.path.join(validation_dir, 'be')\n", - "os.mkdir(validation_b_dir)\n", - "\n", - "validation_h_dir = os.path.join(validation_dir, 'ho')\n", - "os.mkdir(validation_h_dir)\n", - "\n", - "validation_y_dir = os.path.join(validation_dir, 'yun')\n", - "os.mkdir(validation_y_dir)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "#建立測試集資料夾\n", - "test_b_dir = os.path.join(test_dir, 'be')\n", - "os.mkdir(test_b_dir)\n", - "\n", - "test_h_dir = os.path.join(test_dir, 'ho')\n", - "os.mkdir(test_h_dir)\n", - "\n", - "test_y_dir = os.path.join(test_dir, 'yun')\n", - "os.mkdir(test_y_dir)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "#擷取be資料集的圖片範圍\n", - "original_0dataset_dir = 'be'\n", - "fnames = ['be.{}.png'.format(i) for i in range(20)]\n", - "for fname in fnames:\n", - " src = os.path.join(original_0dataset_dir, fname)\n", - " dst = os.path.join(train_b_dir, fname)\n", - " shutil.copyfile(src, dst)\n", - "\n", - "fnames = ['be.{}.png'.format(i) for i in range(45, 54)]\n", - "for fname in fnames:\n", - " src = os.path.join(original_0dataset_dir, fname)\n", - " dst = os.path.join(validation_b_dir, fname)\n", - " shutil.copyfile(src, dst)\n", - "\n", - "fnames = ['be.{}.png'.format(i) for i in range(54, 59)]\n", - "for fname in fnames:\n", - " src = os.path.join(original_0dataset_dir, fname)\n", - " dst = os.path.join(test_b_dir, fname)\n", - " shutil.copyfile(src, dst)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "#擷取ho資料集的圖片範圍\n", - "original_0dataset_dir = 'ho'\n", - "fnames = ['ho.{}.png'.format(i) for i in range(20)]\n", - "for fname in fnames:\n", - " src = os.path.join(original_0dataset_dir, fname)\n", - " dst = os.path.join(train_h_dir, fname)\n", - " shutil.copyfile(src, dst)\n", - "\n", - "fnames = ['ho.{}.png'.format(i) for i in range(45, 54)]\n", - "for fname in fnames:\n", - " src = os.path.join(original_0dataset_dir, fname)\n", - " dst = os.path.join(validation_h_dir, fname)\n", - " shutil.copyfile(src, dst)\n", - "\n", - "fnames = ['ho.{}.png'.format(i) for i in range(54, 59)]\n", - "for fname in fnames:\n", - " src = os.path.join(original_0dataset_dir, fname)\n", - " dst = os.path.join(test_h_dir, fname)\n", - " shutil.copyfile(src, dst)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "#擷取yun資料集的圖片範圍\n", - "original_0dataset_dir = 'yun'\n", - "fnames = ['yun.{}.png'.format(i) for i in range(20)]\n", - "for fname in fnames:\n", - " src = os.path.join(original_0dataset_dir, fname)\n", - " dst = os.path.join(train_y_dir, fname)\n", - " shutil.copyfile(src, dst)\n", - "\n", - "fnames = ['yun.{}.png'.format(i) for i in range(45, 54)]\n", - "for fname in fnames:\n", - " src = os.path.join(original_0dataset_dir, fname)\n", - " dst = os.path.join(validation_y_dir, fname)\n", - " shutil.copyfile(src, dst)\n", - "\n", - "fnames = ['yun.{}.png'.format(i) for i in range(54, 59)]\n", - "for fname in fnames:\n", - " src = os.path.join(original_0dataset_dir, fname)\n", - " dst = os.path.join(test_y_dir, fname)\n", - " shutil.copyfile(src, dst)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "12" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(test_y_dir)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Using TensorFlow backend.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Model: \"sequential_1\"\n", - "_________________________________________________________________\n", - "Layer (type) Output Shape Param # \n", - "=================================================================\n", - "conv2d_1 (Conv2D) (None, 98, 98, 32) 896 \n", - "_________________________________________________________________\n", - "max_pooling2d_1 (MaxPooling2 (None, 49, 49, 32) 0 \n", - "_________________________________________________________________\n", - "conv2d_2 (Conv2D) (None, 47, 47, 64) 18496 \n", - "_________________________________________________________________\n", - "max_pooling2d_2 (MaxPooling2 (None, 23, 23, 64) 0 \n", - "_________________________________________________________________\n", - "conv2d_3 (Conv2D) (None, 21, 21, 128) 73856 \n", - "_________________________________________________________________\n", - "max_pooling2d_3 (MaxPooling2 (None, 10, 10, 128) 0 \n", - "_________________________________________________________________\n", - "conv2d_4 (Conv2D) (None, 8, 8, 128) 147584 \n", - "_________________________________________________________________\n", - "max_pooling2d_4 (MaxPooling2 (None, 4, 4, 128) 0 \n", - "_________________________________________________________________\n", - "flatten_1 (Flatten) (None, 2048) 0 \n", - "_________________________________________________________________\n", - "dense_1 (Dense) (None, 512) 1049088 \n", - "_________________________________________________________________\n", - "dense_2 (Dense) (None, 3) 1539 \n", - "=================================================================\n", - "Total params: 1,291,459\n", - "Trainable params: 1,291,459\n", - "Non-trainable params: 0\n", - "_________________________________________________________________\n" - ] - } - ], - "source": [ - "#建立cnn\n", - "from keras import layers\n", - "from keras import models\n", - "\n", - "model = models.Sequential()\n", - "model.add(layers.Conv2D(32, (3, 3), activation='relu',\n", - " input_shape=(100, 100, 3)))\n", - "model.add(layers.MaxPooling2D((2, 2)))\n", - "model.add(layers.Conv2D(64, (3, 3), activation='relu'))\n", - "model.add(layers.MaxPooling2D((2, 2)))\n", - "model.add(layers.Conv2D(128, (3, 3), activation='relu'))\n", - "model.add(layers.MaxPooling2D((2, 2)))\n", - "model.add(layers.Conv2D(128, (3, 3), activation='relu'))\n", - "model.add(layers.MaxPooling2D((2, 2)))\n", - "model.add(layers.Flatten())\n", - "model.add(layers.Dense(512, activation='relu'))\n", - "model.add(layers.Dense(3, activation='softmax'))\n", - "\n", - "model.summary()" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "#優化器\n", - "from keras import optimizers\n", - "\n", - "model.compile(loss='categorical_crossentropy',\n", - " optimizer=optimizers.RMSprop(lr=1e-4),\n", - " metrics=['acc'])" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Found 60 images belonging to 3 classes.\n", - "Found 27 images belonging to 3 classes.\n" - ] - } - ], - "source": [ - "#ImageDataGenerator套件label圖片\n", - "from keras.preprocessing.image import ImageDataGenerator\n", - "import numpy as np\n", - "train_datagen = ImageDataGenerator(rescale=1./255)\n", - "test_datagen = ImageDataGenerator(rescale=1./255)\n", - "\n", - "train_generator = train_datagen.flow_from_directory(\n", - " train_dir,\n", - " target_size=(100, 100),\n", - " batch_size=20,\n", - " class_mode='categorical')\n", - "\n", - "validation_generator = test_datagen.flow_from_directory(\n", - " validation_dir,\n", - " target_size=(100, 100),\n", - " batch_size=20,\n", - " class_mode='categorical')" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "data batch shape: (20, 100, 100, 3)\n", - "labels batch shape: (20, 3)\n" - ] - } - ], - "source": [ - "for data_batch, labels_batch in train_generator:\n", - " print('data batch shape:', data_batch.shape)\n", - " print('labels batch shape:', labels_batch.shape)\n", - " break" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch 1/30\n", - "100/100 [==============================] - 94s 940ms/step - loss: 0.6316 - acc: 0.7760 - val_loss: 0.8940 - val_acc: 0.7778\n", - "Epoch 2/30\n", - "100/100 [==============================] - 93s 930ms/step - loss: 0.4135 - acc: 0.8530 - val_loss: 0.6577 - val_acc: 0.7037\n", - "Epoch 3/30\n", - "100/100 [==============================] - 94s 941ms/step - loss: 0.2813 - acc: 0.8860 - val_loss: 0.6228 - val_acc: 0.6296\n", - "Epoch 4/30\n", - "100/100 [==============================] - 93s 933ms/step - loss: 0.1676 - acc: 0.9280 - val_loss: 1.7445 - val_acc: 0.5926\n", - "Epoch 5/30\n", - "100/100 [==============================] - 94s 939ms/step - loss: 0.1259 - acc: 0.9370 - val_loss: 1.0945 - val_acc: 0.5926\n", - "Epoch 6/30\n", - "100/100 [==============================] - 94s 942ms/step - loss: 0.1062 - acc: 0.9405 - val_loss: 2.6368 - val_acc: 0.5926\n", - "Epoch 7/30\n", - "100/100 [==============================] - 96s 960ms/step - loss: 0.0993 - acc: 0.9390 - val_loss: 1.2031 - val_acc: 0.5926\n", - "Epoch 8/30\n", - "100/100 [==============================] - 95s 954ms/step - loss: 0.0951 - acc: 0.9305 - val_loss: 2.8705 - val_acc: 0.5926\n", - "Epoch 9/30\n", - "100/100 [==============================] - 96s 957ms/step - loss: 0.0892 - acc: 0.9385 - val_loss: 2.4154 - val_acc: 0.5926\n", - "Epoch 10/30\n", - "100/100 [==============================] - 97s 966ms/step - loss: 0.0860 - acc: 0.9365 - val_loss: 4.6667 - val_acc: 0.5926\n", - "Epoch 11/30\n", - "100/100 [==============================] - 97s 970ms/step - loss: 0.0860 - acc: 0.9365 - val_loss: 2.0964 - val_acc: 0.5926\n", - "Epoch 12/30\n", - "100/100 [==============================] - 97s 973ms/step - loss: 0.0844 - acc: 0.9365 - val_loss: 4.6467 - val_acc: 0.5926\n", - "Epoch 13/30\n", - "100/100 [==============================] - 97s 969ms/step - loss: 0.0842 - acc: 0.9365 - val_loss: 0.8492 - val_acc: 0.5926\n", - "Epoch 14/30\n", - "100/100 [==============================] - 97s 972ms/step - loss: 0.0811 - acc: 0.9345 - val_loss: 6.7441 - val_acc: 0.5926\n", - "Epoch 15/30\n", - "100/100 [==============================] - 97s 971ms/step - loss: 0.0801 - acc: 0.9380 - val_loss: 1.3565 - val_acc: 0.5926\n", - "Epoch 16/30\n", - "100/100 [==============================] - 97s 973ms/step - loss: 0.0775 - acc: 0.9315 - val_loss: 5.6226 - val_acc: 0.5926\n", - "Epoch 17/30\n", - "100/100 [==============================] - 98s 983ms/step - loss: 0.0816 - acc: 0.9315 - val_loss: 5.0703 - val_acc: 0.5926\n", - "Epoch 18/30\n", - "100/100 [==============================] - 98s 984ms/step - loss: 0.0746 - acc: 0.9330 - val_loss: 7.8723 - val_acc: 0.5926\n", - "Epoch 19/30\n", - "100/100 [==============================] - 98s 983ms/step - loss: 0.0747 - acc: 0.9360 - val_loss: 2.2070 - val_acc: 0.5926\n", - "Epoch 20/30\n", - "100/100 [==============================] - 98s 979ms/step - loss: 0.0756 - acc: 0.9320 - val_loss: 8.8935 - val_acc: 0.5926\n", - "Epoch 21/30\n", - "100/100 [==============================] - 98s 983ms/step - loss: 0.0775 - acc: 0.9350 - val_loss: 2.1388 - val_acc: 0.5926\n", - "Epoch 22/30\n", - "100/100 [==============================] - 98s 984ms/step - loss: 0.0734 - acc: 0.9360 - val_loss: 4.9511 - val_acc: 0.5926\n", - "Epoch 23/30\n", - "100/100 [==============================] - 98s 982ms/step - loss: 0.0729 - acc: 0.9335 - val_loss: 1.6979 - val_acc: 0.5926\n", - "Epoch 24/30\n", - "100/100 [==============================] - 99s 988ms/step - loss: 0.0718 - acc: 0.9325 - val_loss: 3.6615 - val_acc: 0.5926\n", - "Epoch 25/30\n", - "100/100 [==============================] - 98s 983ms/step - loss: 0.0729 - acc: 0.9375 - val_loss: 6.6448 - val_acc: 0.5926\n", - "Epoch 26/30\n", - "100/100 [==============================] - 98s 984ms/step - loss: 0.0721 - acc: 0.9355 - val_loss: 6.3982 - val_acc: 0.5926\n", - "Epoch 27/30\n", - "100/100 [==============================] - 98s 980ms/step - loss: 0.0711 - acc: 0.9340 - val_loss: 12.2808 - val_acc: 0.5926\n", - "Epoch 28/30\n", - "100/100 [==============================] - 98s 980ms/step - loss: 0.0721 - acc: 0.9365 - val_loss: 7.8047 - val_acc: 0.5926\n", - "Epoch 29/30\n", - "100/100 [==============================] - 98s 980ms/step - loss: 0.0704 - acc: 0.9310 - val_loss: 9.7293 - val_acc: 0.5926\n", - "Epoch 30/30\n", - "100/100 [==============================] - 98s 982ms/step - loss: 0.0737 - acc: 0.9360 - val_loss: 6.4731 - val_acc: 0.5926\n" - ] - } - ], - "source": [ - "#epoch訓練30\n", - "history = model.fit_generator(\n", - " train_generator,\n", - " steps_per_epoch=100,\n", - " epochs=30,\n", - " validation_data=validation_generator,\n", - " validation_steps=50)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "model.save('train1.h5')" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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OHK8lOMlZRwvLStfdr4mcRHB5atudnAk3MnxEbSLDScsOJDgQCEkMICgwACCA4XggIA6T+r0Bk2uG8HEiRO59NJLmTVrVvm2a665hksuuYT09HT69u1Lt241d3647bbbuP766+nduzd9+/Zl4MCBgG2H169fP3r27EmnTp0YOnRo+TE333wzo0ePpm3btsybN698e//+/Zk8eXL5OW688Ub69etXZQlIZfPnz6d9+/bliTXYZD0jI4Ndu3bx1ltvccstt/Dggw8SHBzMe++9x6hRo1i1ahXp6emEhIRw4YUX8re//Y177rmHK664grfeeotzzz232tes7r3q2bMn999/P2effTaBgYH069eP119/vfyYBx54oMIfNH4vNhmCwqCkUNvwKaWUahStY8IY1avqktWalJYZm2iXlFFUWlr+dUFRCdkHjrF9/1F27D/K9v1HycjJ56u1uykurT0hDwwQggOF0KBAUltG0LlVFGmtoklrFUVa6yiS4ry/fL3UVCLgT9LT082KFSsqbFu3bh3du3f3UkTKm95//30+/vjjGkfk/fL746VhkLcJ/pQDAYHejkZVQ0RWGmOqb0Kv6q2qa71Syv+Vlhn25Beyff9Rdh8qLB8BLy4to6TUlH9tb4ajx0vIzDvKpr2H2ZNfVH6eUEcHlrRWUXROjEIEO8pePupeXPFxUQlXnZHM1NF1a29b03VeR65Vk/Pb3/6WOXPmNGhfb5/R8WyIaqOJtVJKqSYlMEBoFxtOu9iT2//WJr+wmM17C9i8p4BNew+zaW8BK7PsIj0AYcEBRIUGExMWVF4vnhwfQVRYENGO1TkbkibXqsn597//7e0QPOeCx7wdgVJKKeVTYsKC6Z8cR//kuArbC4tLHWUkAY0ajybXSimllFKqyQkL9s6nvI2byntBU6kpVw1Lvy+UUkop5QlNOrkOCwtj3759mkipCowx7Nu3r3yRG6WUUkqphtKky0KSkpLIzs4mNzfX26EoHxMWFkZSUpK3w1CqSRORUcA/gUDgVWPM45Wevxu4ESgBcoEbjDE1N/1XSikf59Hk2o0L62TgSWCnY9NzxphXHc9dBzzg2P6oMeaNur5+cHAwHTt2rGf0Siml6ktEAoHngZFANrBcRGYbYzJcdvsJSDfGHBWR24AngCsbP1qllGo4Hkuu3bywArxrjJlS6dh44C9AOmCA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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "#可視化結果\n", - "f, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n", - "t = f.suptitle('Basic CNN Performance', fontsize=12)\n", - "f.subplots_adjust(top=0.85, wspace=0.3)\n", - "\n", - "epoch_list = list(range(1,31))\n", - "ax1.plot(epoch_list, history.history['acc'], label='Train Accuracy')\n", - "ax1.plot(epoch_list, history.history['val_acc'], label='Validation Accuracy')\n", - "ax1.set_xticks(np.arange(0, 31, 5))\n", - "ax1.set_ylabel('Accuracy Value')\n", - "ax1.set_xlabel('Epoch')\n", - "ax1.set_title('Accuracy')\n", - "l1 = ax1.legend(loc=\"best\")\n", - "\n", - "ax2.plot(epoch_list, history.history['loss'], label='Train Loss')\n", - "ax2.plot(epoch_list, history.history['val_loss'], label='Validation Loss')\n", - "ax2.set_xticks(np.arange(0, 31, 5))\n", - "ax2.set_ylabel('Loss Value')\n", - "ax2.set_xlabel('Epoch')\n", - "ax2.set_title('Loss')\n", - "l2 = ax2.legend(loc=\"best\")" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Model: \"sequential_2\"\n", - "_________________________________________________________________\n", - "Layer (type) Output Shape Param # \n", - "=================================================================\n", - "conv2d_5 (Conv2D) (None, 98, 98, 32) 896 \n", - "_________________________________________________________________\n", - "max_pooling2d_5 (MaxPooling2 (None, 49, 49, 32) 0 \n", - "_________________________________________________________________\n", - "conv2d_6 (Conv2D) (None, 47, 47, 64) 18496 \n", - "_________________________________________________________________\n", - "max_pooling2d_6 (MaxPooling2 (None, 23, 23, 64) 0 \n", - "_________________________________________________________________\n", - "conv2d_7 (Conv2D) (None, 21, 21, 128) 73856 \n", - "_________________________________________________________________\n", - "max_pooling2d_7 (MaxPooling2 (None, 10, 10, 128) 0 \n", - "_________________________________________________________________\n", - "conv2d_8 (Conv2D) (None, 8, 8, 128) 147584 \n", - "_________________________________________________________________\n", - "max_pooling2d_8 (MaxPooling2 (None, 4, 4, 128) 0 \n", - "_________________________________________________________________\n", - "flatten_2 (Flatten) (None, 2048) 0 \n", - "_________________________________________________________________\n", - "dropout_1 (Dropout) (None, 2048) 0 \n", - "_________________________________________________________________\n", - "dense_3 (Dense) (None, 512) 1049088 \n", - "_________________________________________________________________\n", - "dense_4 (Dense) (None, 3) 1539 \n", - "=================================================================\n", - "Total params: 1,291,459\n", - "Trainable params: 1,291,459\n", - "Non-trainable params: 0\n", - "_________________________________________________________________\n" - ] - } - ], - "source": [ - "#套入VGG16模型\n", - "from keras.applications import VGG16\n", - "\n", - "\n", - "conv_base = VGG16(weights='imagenet',\n", - " include_top=False,\n", - " input_shape=(100,100, 3))\n", - "model.summary()" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Found 60 images belonging to 3 classes.\n", - "[[1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [1. 0. 0.]\n", - " [0. 1. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [0. 1. 0.]\n", - " [1. 0. 0.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [1. 0. 0.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]]\n", - "[[0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [0. 1. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [0. 1. 0.]]\n", - "[[0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [0. 1. 0.]\n", - " [0. 1. 0.]\n", - " [1. 0. 0.]\n", - " [0. 1. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [0. 0. 1.]]\n", - "Found 27 images belonging to 3 classes.\n", - "[[0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [1. 0. 0.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [1. 0. 0.]\n", - " [0. 1. 0.]\n", - " [0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [1. 0. 0.]\n", - " [0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [0. 1. 0.]]\n", - "Found 15 images belonging to 3 classes.\n", - "[[0. 1. 0.]\n", - " [1. 0. 0.]\n", - " [1. 0. 0.]\n", - " [0. 1. 0.]\n", - " [1. 0. 0.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [1. 0. 0.]\n", - " [0. 0. 1.]\n", - " [0. 0. 1.]\n", - " [0. 1. 0.]\n", - " [1. 0. 0.]]\n" - ] - } - ], - "source": [ - "#使用conv_base的模型先抽取特徵跟label產出,將特徵提取後進行降維輸出\n", - "import os\n", - "import numpy as np\n", - "from keras.preprocessing.image import ImageDataGenerator\n", - "\n", - "base_dir = 'Rec'\n", - "\n", - "train_dir = os.path.join(base_dir, 'train')\n", - "validation_dir = os.path.join(base_dir, 'validation')\n", - "test_dir = os.path.join(base_dir, 'test')\n", - "\n", - "datagen = ImageDataGenerator(rescale=1./255)\n", - "batch_size = 20\n", - "\n", - "def extract_features(directory, sample_count):\n", - " features = np.zeros(shape=(sample_count, 3, 3, 512))\n", - " labels = np.zeros(shape=(sample_count,3))\n", - " generator = datagen.flow_from_directory(\n", - " directory,\n", - " target_size=(100, 100),\n", - " batch_size=batch_size,\n", - " class_mode='categorical'\n", - " )\n", - " i = 0\n", - " for inputs_batch, labels_batch in generator:\n", - " features_batch = conv_base.predict(inputs_batch)\n", - " features[i * batch_size : (i + 1) * batch_size] = features_batch\n", - " print(labels_batch)\n", - " labels[i * batch_size : (i + 1) * batch_size] = labels_batch\n", - " i += 1\n", - " if i * batch_size >= sample_count:\n", - " \n", - " break\n", - " return features, labels\n", - "\n", - "train_features, train_labels = extract_features(train_dir, 60)\n", - "validation_features, validation_labels = extract_features(validation_dir, 20)\n", - "test_features, test_labels = extract_features(test_dir, 15)" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [], - "source": [ - "train_features = np.resize(train_features, (60, 3 * 3 * 512))\n", - "validation_features = np.resize(validation_features, (20, 3 * 3 * 512))\n", - "test_features = np.resize(test_features, (15, 3 * 3 * 512))" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Train on 60 samples, validate on 20 samples\n", - "Epoch 1/30\n", - "60/60 [==============================] - 1s 10ms/step - loss: 2.0313 - acc: 0.3167 - val_loss: 1.8868 - val_acc: 0.3000\n", - "Epoch 2/30\n", - "60/60 [==============================] - 0s 483us/step - loss: 1.8181 - acc: 0.3333 - val_loss: 1.7381 - val_acc: 0.3000\n", - "Epoch 3/30\n", - "60/60 [==============================] - 0s 566us/step - loss: 1.6853 - acc: 0.3000 - val_loss: 1.6217 - val_acc: 0.3000\n", - "Epoch 4/30\n", - "60/60 [==============================] - 0s 550us/step - loss: 1.6355 - acc: 0.3167 - val_loss: 1.5229 - val_acc: 0.3000\n", - "Epoch 5/30\n", - "60/60 [==============================] - 0s 483us/step - loss: 1.5393 - acc: 0.3333 - val_loss: 1.4473 - val_acc: 0.3000\n", - "Epoch 6/30\n", - "60/60 [==============================] - 0s 550us/step - loss: 1.5782 - acc: 0.2833 - val_loss: 1.3734 - val_acc: 0.3000\n", - "Epoch 7/30\n", - "60/60 [==============================] - 0s 533us/step - loss: 1.4986 - acc: 0.2833 - val_loss: 1.3062 - val_acc: 0.3000\n", - "Epoch 8/30\n", - "60/60 [==============================] - 0s 500us/step - loss: 1.4321 - acc: 0.3667 - val_loss: 1.2484 - val_acc: 0.3000\n", - "Epoch 9/30\n", - "60/60 [==============================] - 0s 583us/step - loss: 1.3253 - acc: 0.3333 - val_loss: 1.1981 - val_acc: 0.3000\n", - "Epoch 10/30\n", - "60/60 [==============================] - 0s 566us/step - loss: 1.2468 - acc: 0.4167 - val_loss: 1.1543 - val_acc: 0.3000\n", - "Epoch 11/30\n", - "60/60 [==============================] - 0s 566us/step - loss: 1.1066 - acc: 0.4500 - val_loss: 1.1124 - val_acc: 0.3000\n", - "Epoch 12/30\n", - "60/60 [==============================] - 0s 600us/step - loss: 1.2571 - acc: 0.3333 - val_loss: 1.0764 - val_acc: 0.3000\n", - "Epoch 13/30\n", - "60/60 [==============================] - 0s 566us/step - loss: 1.1691 - acc: 0.4667 - val_loss: 1.0375 - val_acc: 0.3500\n", - "Epoch 14/30\n", - "60/60 [==============================] - 0s 550us/step - loss: 1.1005 - acc: 0.5167 - val_loss: 1.0097 - val_acc: 0.3500\n", - "Epoch 15/30\n", - "60/60 [==============================] - 0s 566us/step - loss: 1.1293 - acc: 0.4167 - val_loss: 0.9818 - val_acc: 0.4000\n", - "Epoch 16/30\n", - "60/60 [==============================] - 0s 516us/step - loss: 1.1421 - acc: 0.4167 - val_loss: 0.9571 - val_acc: 0.4000\n", - "Epoch 17/30\n", - "60/60 [==============================] - 0s 533us/step - loss: 1.0784 - acc: 0.5000 - val_loss: 0.9312 - val_acc: 0.5500\n", - "Epoch 18/30\n", - "60/60 [==============================] - 0s 516us/step - loss: 1.0378 - acc: 0.4500 - val_loss: 0.9119 - val_acc: 0.6000\n", - "Epoch 19/30\n", - "60/60 [==============================] - 0s 533us/step - loss: 0.9446 - acc: 0.5000 - val_loss: 0.8883 - val_acc: 0.7500\n", - "Epoch 20/30\n", - "60/60 [==============================] - 0s 533us/step - loss: 0.9756 - acc: 0.5167 - val_loss: 0.8679 - val_acc: 0.7500\n", - "Epoch 21/30\n", - "60/60 [==============================] - 0s 633us/step - loss: 0.9451 - acc: 0.5667 - val_loss: 0.8540 - val_acc: 0.7500\n", - "Epoch 22/30\n", - "60/60 [==============================] - 0s 566us/step - loss: 0.7960 - acc: 0.6500 - val_loss: 0.8393 - val_acc: 0.7500\n", - "Epoch 23/30\n", - "60/60 [==============================] - 0s 566us/step - loss: 0.8670 - acc: 0.5833 - val_loss: 0.8223 - val_acc: 0.7500\n", - "Epoch 24/30\n", - "60/60 [==============================] - 0s 600us/step - loss: 0.9493 - acc: 0.6167 - val_loss: 0.8102 - val_acc: 0.7500\n", - "Epoch 25/30\n", - "60/60 [==============================] - 0s 566us/step - loss: 0.9749 - acc: 0.5500 - val_loss: 0.7922 - val_acc: 0.7500\n", - "Epoch 26/30\n", - "60/60 [==============================] - 0s 583us/step - loss: 0.9339 - acc: 0.6333 - val_loss: 0.7809 - val_acc: 0.8000\n", - "Epoch 27/30\n", - "60/60 [==============================] - 0s 550us/step - loss: 0.7419 - acc: 0.7000 - val_loss: 0.7721 - val_acc: 0.8000\n", - "Epoch 28/30\n", - "60/60 [==============================] - 0s 583us/step - loss: 0.8690 - acc: 0.6167 - val_loss: 0.7634 - val_acc: 0.8000\n", - "Epoch 29/30\n", - "60/60 [==============================] - 0s 583us/step - loss: 0.8348 - acc: 0.6167 - val_loss: 0.7556 - val_acc: 0.8000\n", - "Epoch 30/30\n", - "60/60 [==============================] - 0s 533us/step - loss: 0.7058 - acc: 0.7000 - val_loss: 0.7460 - val_acc: 0.8000\n" - ] - } - ], - "source": [ - "#建立優化防止梯度下降訓練\n", - "from keras import models\n", - "from keras import layers\n", - "from keras import optimizers\n", - "\n", - "model = models.Sequential()\n", - "model.add(layers.Dense(256, activation='relu', input_dim=3 * 3 * 512))\n", - "model.add(layers.Dropout(0.5))\n", - "model.add(layers.Dense(3, activation='softmax'))\n", - "\n", - "model.compile(optimizer=optimizers.RMSprop(lr=2e-5),\n", - " loss='categorical_crossentropy',\n", - " metrics=['acc'])\n", - "\n", - "history = model.fit(train_features, train_labels,\n", - " epochs=30,\n", - " batch_size=100,\n", - " validation_data=(validation_features, validation_labels))" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [], - "source": [ - "model.save('train3.h5')" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAtAAAAEjCAYAAAAbuTa2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOzdd3iUVfbA8e9JIwQSIA2EAEFqACkhUgTpsiIqIqyCYEGxrW2Lrui6rrr6s3dcFRVsCBYUcRVRuopSQhNIqAYJLSEBAoEASc7vj3eSDZAygZlMEs7neeYh88597z0zCTNn7nuLqCrGGGOMMcYY9/j5OgBjjDHGGGOqEkugjTHGGGOMKQdLoI0xxhhjjCkHS6CNMcYYY4wpB0ugjTHGGGOMKQdLoI0xxhhjjCkHS6CNMWctEZklItf7Og5fEMdkEdknIkt9HY8xxlQllkAbYyo9EUkRkSMicsiV8H0tIo3PtF5VHayq751GPCIid4vIWhHJFpFUEflURM5zPf6uiKiIdC1yTgsR0SL3F4hITtHnISIDRSSllHbV1d4hEdkhIi+IiH9543fpBVwExKhq17IKG2OM+R9LoI0xVcVlqlobOAfYA7zqw1heBu4B7gbCgVbADGBIkTKZwONl1JMN/LOcbXd0vQ4DgGuAm8t5PiISADQFUlQ1+zTPN8aYs5Yl0MaYKkVVc4DPgLYFx0RkiIisFJEsEdkuIo8UeSxYRD4UkQwR2S8iy0SkvuuxBSIyrkjZm0UkSUQOish6EYk/uX0RaQncAYxS1XmqelRVD6vqFFV9qkjR94AOItKnlKfzCjBKRFqcxuuQDPwAtHfF1VBEpotIuoj8JiJ3F4n5ERH5zPU6ZAE3AW8DPVy92Y8Wef6bRSRTRGaKSMMidaiI3CEim4BNRY79SUQ2uV6zf4tIcxH52fW7+EREglxl64nIf13x7XP9HFOk/gWu839y1fWdiEQWebyXiCx2/Q63i8gNruM1ROQ5EfldRPaIyBsiUrO8r6cxxpSHJdDGmCpFREKAq4FfihzOBq4D6uL0At8uIle4HrseqAM0BiKA24AjxdT7R+ARVz1hwOVARjEhDABSVbWsccOHgf8DniilzA7gLVe75SIibYELgZUi4gd8BawGGrli/LOI/KHIKUNxvnjUBd7HeR1+VtXaqvovEekPPAlchdPLvw2YdlKzVwDdKPLlBbgY6AJ0B/4OTARG47ze7YFRrnJ+wGScnu8mOL+DCSfVfw0wFogGgoB7Xc+1CTAL56pDFNAJWOU652mcKwCdgBau5/9waa+dMcacKUugjTFVxQwR2Q9k4YzdfbbgAVVdoKq/qmq+qq4BpgIFPb/HcRLnFqqap6qJqppVTP3jgGdUdZk6NqvqtmLKRQC73Iz5TaCJiAwupcyTwGUi0s7NOleIyD6chPltnKT0fCBKVR9T1WOquhUnMR9Z5LyfVXWG6zU65QsETtI7SVVXqOpR4AGcHurYorGqauZJ5z+tqlmqug5YC3ynqltV9QBO0tsZQFUzVHW6q7f+IM4Xi5N75yer6kZX/Z/gJMUFsc1R1amqetxV1yoREZwhLH9xxXUQ50vLSIwxxotsHJsxpqq4QlXnuCbNDQUWikhbVd0tIt2Ap3B6PIOAGsCnrvM+wOkNnSYidYEPgX+o6vGT6m8MbHEjjgycHtoyqepREfk38G/+1xN7cpl0EZkAPAa87ka18aq6uegBEWkKNHR9wSjgjzPEo8D2MuptCKwoEtchEcnA6dFNKaWOPUV+PlLM/QauGEOAF3F6rOu5Hg8VEX9VzXPd313k3MNAbdfPJf1uooAQINHJpQEQnOdujDFeYz3QxpgqxdWL/DmQh7OSBMBHwEygsarWAd7ASaRw9Vg+qqptgQuAS3GGaZxsO9DcjRDmAjEikuBmyJNxhpAMK6XMs0A/nKEQp2M78Juq1i1yC1XVS4qU0ZJOdtmJM7wCABGphdPbvqMcdZTmb0BroJuqhgG9C5py49ySfjd7cZL0dkWedx3XJEtjjPEaS6CNMVWKOIbi9GImuQ6HApmqmuNaOu6aIuX7ich5rp7rLJwhHXkn14szHOJeEeniaqOFq2f3BKq6CfgPMFVE+opIkGui4kgRGV9M+VycMc73l/ScVHU/8DzOGOLTsRTIEpH7RaSmiPiLSHsROb8cdXwEjBWRTiJSA2coxBJVTTnNmE4WipPs7heRcOBf5Th3CjBQRK4SkQARiRCRTqqajzNU5UURiQYQkUYnjf02xhiPswTaGFNVfCUih3CS4CeA613jbgH+BDwmIgdxJpB9UuS8BjiT57JwEu6FOMM4TqCqn7rq/Qg4iLMsXXgJsdyNMwHuNWA/zvCCYTjjkoszlbLHTb9M8Yl9mVxDIC7DGTP8G07P7Ns4Pd/u1jEXZ0m96a5Ym+PZscQvATVdsf0CfFuO2H4HLsHpxc7EmUDY0fXw/cBm4BfXCiNzcHq6jTHGa0T1TK7IGWOMMcYYc3axHmhjjDHGGGPKwRJoY4wxxhhjysESaGOMMcYYY8rBEmhjjDHGGGPKwRJoY4wxxhhjysESaGOMMcYYY8rBEmhjjDHGGGPKwRJoY4wxxhhjysESaGOMMcYYY8rBEmhjjDHGGGPKwRJoY4wxxhhjysESaGOMMcYYY8rBEmhT6YjIAhHZJyI1fB2LMcaYykFEUkRkoK/jMAYsgTaVjIjEAhcCClxege0GVFRbxhhjjKnaLIE2lc11wC/Au8D1BQdFpKaIPC8i20TkgIj8KCI1XY/1EpHFIrJfRLaLyA2u4wtEZFyROm4QkR+L3FcRuUNENgGbXMdedtWRJSKJInJhkfL+IvKgiGwRkYOuxxuLyGsi8nzRJyEiX4nIn73xAhljjPkfEblZRDaLSKaIzBSRhq7jIiIvikia63NjjYi0dz12iYisd72X7xCRe337LExVYwm0qWyuA6a4bn8Qkfqu488BXYALgHDg70C+iDQBZgGvAlFAJ2BVOdq7AugGtHXdX+aqIxz4CPhURIJdj/0VGAVcAoQBNwKHgfeAUSLiByAikcAAYGp5nrgxxpjyEZH+wJPAVcA5wDZgmuvhQUBvoBVQF7gayHA99g5wq6qGAu2BeRUYtqkGLIE2lYaI9AKaAp+oaiKwBbjGlZjeCNyjqjtUNU9VF6vqUWA0MEdVp6rqcVXNUNXyJNBPqmqmqh4BUNUPXXXkqurzQA2gtavsOOAhVd2gjtWuskuBAzhJM8BIYIGq7jnDl8QYY0zpRgOTVHWF6zPhAaCHazjgcSAUaAOIqiap6i7XeceBtiISpqr7VHWFD2I3VZgl0KYyuR74TlX3uu5/5DoWCQTjJNQna1zCcXdtL3pHRP4mIkmuy337gTqu9stq6z1gjOvnMcAHZxCTMcYY9zTE6XUGQFUP4fQyN1LVecAE4DVgj4hMFJEwV9HhOFcTt4nIQhHpUcFxmyrOEmhTKbjGM18F9BGR3SKyG/gL0BHnslwO0LyYU7eXcBwgGwgpcr9BMWW0SAwXAve74qinqnVxepbFjbY+BIaKSEcgDphRQjljjDGesxPnyiUAIlILiAB2AKjqK6raBWiHM5TjPtfxZao6FIjGeb/+pILjNlWcJdCmsrgCyMMZi9zJdYsDfsAZFz0JeEFEGrom8/VwLXM3BRgoIleJSICIRIhIJ1edq4ArRSRERFoAN5URQyiQC6QDASLyMM5Y5wJvA/8WkZauySkdRCQCQFVTccZPfwBMLxgSYowxxqMCRSS44IaT+I4VkU6uz4T/A5aoaoqInC8i3UQkEKdDJQfIE5EgERktInVU9TiQhfP5Y4zbLIE2lcX1wGRV/V1VdxfccC6/jQbGA7/iJKmZwNOAn6r+jnMZ7m+u46tweq0BXgSOAXtwhlhMKSOG2TgTEjfiXBLM4cQhHi/gvFl/h/OG+w5Qs8jj7wHnYcM3jDHGW74BjhS5XQj8E5gO7MK5SjjSVTYMeAvYh/OenoEzIR3gWiBFRLKA2/jfEDxj3CKqWnYpY0yZRKQ3zlCOWFXN93U8xhhjjPEO64E2xgNclwjvAd625NkYY4yp3iyBNuYMiUgcsB9nsuNLPg7HGGOMMV5mQziMMcYYY4wpB+uBNsYYY4wxphwCfB1AeUVGRmpsbKyvwzDGnOUSExP3qmqUr+Ooruy93hhTGZT0Xl/lEujY2FiWL1/u6zCMMWc5EdlWdilzuuy93hhTGZT0Xm9DOIwxxhhjjCkHS6CNMcYYY4wpB0ugjTHGGGOMKYcqNwa6OMePHyc1NZWcnBxfh2IqkeDgYGJiYggMDPR1KMYYY84Clo9UXeXNGbyaQIvIxcDLgD/ODm1PnfR4E+A9oK6rzHhV/aa87aSmphIaGkpsbCwi4oHITVWnqmRkZJCamkqzZs18HY4xxpizgOUjVdPp5AxeG8IhIv7Aa8BgoC0wSkTanlTsIeATVe0MjAT+czpt5eTkEBERYX+sppCIEBERYb0AxhhjKozlI1XT6eQM3uyB7gpsVtWtACIyDRgKrC9SRoEw1891gJ2n25j9sZqT2d9EJaQK25dCbiX7YlOzHpzTwddRmNOUn6+s2XGAOjUDaRZZy9fhmLOcffZUTeX9vXkzgW4EbC9yPxXodlKZR4DvROQuoBYwsLiKROQW4BaAJk2aeDxQY0wFWT0VZtzu6yhO1bw/XPuFr6MwpyknN4+r3vyZ0d2a8K/L2vk6HGPMWcCbCXRxqbyedH8U8K6qPi8iPYAPRKS9quafcJLqRGAiQEJCwsl1+FxGRgYDBgwAYPfu3fj7+xMV5Wxas3TpUoKCgsqsY+zYsYwfP57WrVuXq+0hQ4aQlZXFDz/8UP7AjalIebmw8BlocB5c/LSvozlRzbq+jsCcgZCgAHo2j2BuUhoPX9rWegDNWcsX+cjbb7/N2rVreemll04/8CrImwl0KtC4yP0YTh2icRNwMYCq/iwiwUAkkObFuDwuIiKCVatWAfDII49Qu3Zt7r333hPKqCqqip9f8cPOJ0+eXO52MzIy+PXXXwkODub333/3Wu98bm4uAQHVYsEW40u/fgL7foORH0FsT19HYzxARBoD7wMNgHxgoqq+fFIZwZlMfglwGLhBVVd4Opb+cfWZv2EtW9IP0SI61NPVG1Ml+CofORt5cx3oZUBLEWkmIkE4kwRnnlTmd2AAgIjEAcFAuhdjqlCbN2+mffv23HbbbcTHx7Nr1y5uueUWEhISaNeuHY899lhh2V69erFq1Spyc3OpW7cu48ePp2PHjvTo0YO0tOK/T3z22WdcccUVXH311Xz88ceFx3fv3s3QoUPp0KEDHTt2ZMmSJYDzn6Lg2NixYwEYM2YMM2bMKDy3du3aAMyZM4eBAwcycuRIOnfuDMBll11Gly5daNeuHW+//XbhOV9//TXx8fF07NiRQYMGkZeXR4sWLcjMzAQgLy+Pc889t/C+OQvl5cKiZ53e59aX+Doa4zm5wN9UNQ7oDtxRzGTxwUBL1+0W4HVvBDKgTTQAc5OqVP+LMRXC2/lIcT788EPOO+882rdvz4MPPgg4HXLXXntt4fFXXnkFgBdffJG2bdvSsWNHxowZ49kn7yVe61ZU1VwRuROYjbNE3SRVXScijwHLVXUm8DfgLRH5C87wjhtU9YyGaDz61TrW78w60/BP0LZh2GmPq1u/fj2TJ0/mjTfeAOCpp54iPDyc3Nxc+vXrx4gRI2jb9sTPmwMHDtCnTx+eeuop/vrXvzJp0iTGjx9/St1Tp07lySefpE6dOowZM4b77rsPgDvuuIOLLrqIO++8k9zcXA4fPszq1at5+umnWbx4MeHh4W4ls7/88gvr168v7Nl+7733CA8P5/DhwyQkJDB8+HCOHj3K7bffzg8//EDTpk3JzMzE39+fUaNG8dFHH3HnnXcye/Zszj//fMLDw0/rNTTVwK+fQuZWuHoK2OX1akNVdwG7XD8fFJEknPkvRSeLDwXed723/yIidUXkHNe5HtOwbk3izgljblIat/Zp7smqjTktZ1M+crLU1FQeeughli9fTp06dRg4cCD//e9/iYqKYu/evfz6668A7N+/H4BnnnmGbdu2ERQUVHissvPqToSq+o2qtlLV5qr6hOvYw67kGVVdr6o9VbWjqnZS1e+8GY8vNG/enPPPP7/w/tSpU4mPjyc+Pp6kpCTWr19/yjk1a9Zk8ODBAHTp0oWUlJRTyuzYsYPff/+d7t2707ZtW/Ly8khOTgZgwYIF3HrrrQAEBAQQFhbGvHnzuPrqqwuTWHeS2R49epwwLOTFF18s/BaamprKli1b+Pnnn+nXrx9NmzY9od6bbrqJ9957D4BJkyYV9nibs1BB73P986DNEF9HY7xERGKBzsCSkx4qbkJ5oxLquEVElovI8vT08l+MHBgXzfJtmew/fKzc5xpT3XkrHynOkiVL6N+/P5GRkQQGBnLNNdewaNEiWrRowYYNG7jnnnuYPXs2derUAaBdu3aMGTOGKVOmVJnNz6rdwNbKNgO7Vq3/Lam0adMmXn75ZZYuXUrdunUZM2ZMsWsOFh3k7+/vT25u7illPv74YzIyMgoX/D5w4ADTpk3jkUceAU5djkVVi51YExAQQH6+M2czLy/vhLaKxj5nzhwWLVrEL7/8Qs2aNenVqxc5OTkl1hsbG0u9evWYP38+K1euZNCgQcW+PuYssHY6ZG6Bqz6w3udqSkRqA9OBP6vqyV1u7kwodw6e4YTx/m2ieXXeZhZsSOeKzsXm6MZUmLMlHylOSYMJIiIiWLNmDbNmzeKVV15h+vTpTJw4kdmzZ7Nw4UK+/PJLHn/8cdauXYu/v385n2HF8moPtDlRVlYWoaGhhIWFsWvXLmbPnn3adU2dOpU5c+aQkpJCSkoKS5cuZerUqQD069ev8BJNXl4eWVlZDBw4kGnTphUO3Sj4NzY2lsTERAC++OIL8vLyim3vwIEDhIeHU7NmTdatW8eyZcsA6NmzJ/PmzWPbtm0n1AtOL/To0aMZOXJkiZMVTDWXn+f0Pke3gzaX+joa4wUiEoiTPE9R1c+LKeLOhHKP6BhTl8jaQcxNtnHQxpTGk/lIcbp37878+fPJyMggNzeXadOm0adPH9LT01FV/vjHP/Loo4+yYsUK8vLySE1NpX///jz77LOkp6dz+PBhj8bjDdWuB7oyi4+Pp23btrRv355zzz2Xnj1PbyWCLVu2sHv3bhISEgqPtWzZkho1apCYmMiECRO4+eabefPNNwkICODNN9+ka9eu/P3vf6d3794EBATQpUsX3nnnHW699VaGDh3K999/z6BBg6hRo0axbQ4ZMoSJEyfSsWNH2rRpQ7duzpLe9evX5/XXX2fo0KGoKg0bNmTWrFkADBs2jBtvvJEbbrjhtJ6nqQbWfg4Zm+CP74F9iap2XCtsvAMkqeoLJRSbCdzp2kyrG3DA0+OfC/j5Cf1aR/Ptut0cz8sn0N/+5owpjqfykQLvvPMOn332WeH95cuX89hjj9G3b19Ulcsuu4whQ4awYsUKbrrppsKr108//TS5ublcc801HDx4kPz8fO6//35CQyv/SjpyhnP2KlxCQoIuX778hGNJSUnExcX5KCJTkl9++YUHHniA+fPn+ywG+9vwofw8eK0b+AfCbT9VuwRaRBJVNaHsktWXiPQCfgB+xVnGDuBBoAmAqr7hSrIn4CxZehgYq6rLi6nuBMW917vj27W7ue3DRKbe3J0ezSPKfb4xZ8I+c6q24n5/Jb3XWw+08YonnniCiRMnMm3aNF+HYnxl3Reu3ud3q13ybByq+iPFj3EuWkaBOyomIriwZSRB/n7MTdpjCbQxxmvsU814xT/+8Q+2bdtGjx49fB2K8YX8PGfXwag4iBvq62jMWaRWjQC6N49gno2DNsZ4kSXQxhjPWz8D9m6APvdZ77OpcAPaRLN1bzZb0w/5OhRjTDVln2zGGM/Kz3f1PreBtlf4OhpzFurv2pXQeqGNMd5iCbQxxrPWz4D0ZOh9H/hV7nU8TfXUODyE1vVDmZO0x9ehGGOqKUugjTGeU9D7HNkK2g3zdTTmLDYgLpplKfs4cOS4r0MxxlRDlkB7QN++fU9ZhPyll17iT3/6U6nn1a5dG4CdO3cyYsSIEusuaymnl1566YRFxy+55BKP7iXfsWNHRo0a5bH6TDWWNBPSk6D336332fjUgLho8vKVhRvLvyW4MVVVdc1HHnnkEZ577rkzrseTLIH2gFGjRp2yXNu0adPcTjobNmx4wgLk5XXyH+w333xD3bp1T7u+opKSksjPz2fRokVkZ2d7pM7iuLs9qKnECnqfI1pC+yt9HY05y3VqXI/wWkHMs2Ec5ixSnfORysbWgfaAESNG8NBDD3H06FFq1KhBSkoKO3fupFevXhw6dIihQ4eyb98+jh8/zuOPP87QoScu65WSksKll17K2rVrOXLkCGPHjmX9+vXExcVx5MiRwnK33347y5Yt48iRI4wYMYJHH32UV155hZ07d9KvXz8iIyOZP38+sbGxLF++nMjISF544QUmTZoEwLhx4/jzn/9MSkoKgwcPplevXixevJhGjRrx5ZdfUrNmzVOe20cffcS1115LUlISM2fOLPxPuHnzZm677TbS09Px9/fn008/pXnz5jzzzDN88MEH+Pn5MXjwYJ566in69u3Lc889R0JCAnv37iUhIYGUlBTeffddvv76a3JycsjOzmbmzJklvlbvv/8+zz33HCJChw4d+M9//kOHDh3YuHEjgYGBZGVl0aFDBzZt2kRgYKC3ftVn7nAmvDsEjnjuCkGloXlwaA9c+Zb1Phuf8/cT+raOYm5SGrl5+QTYroTmLFCd85HiFFdndnY2V111FampqeTl5fHPf/6Tq6++mvHjxzNz5kwCAgIYNGjQGfdoV78EetZ42P2rZ+tscB4MfqrEhyMiIujatSvffvstQ4cOZdq0aVx99dWICMHBwXzxxReEhYWxd+9eunfvzuWXX46zOdepXn/9dUJCQlizZg1r1qwhPj6+8LEnnniC8PBw8vLyGDBgAGvWrOHuu+/mhRdeYP78+URGRp5QV2JiIpMnT2bJkiWoKt26daNPnz7Uq1ePTZs2MXXqVN566y2uuuoqpk+fzpgxY06J5+OPP+b7779nw4YNTJgwoTCBHj16NOPHj2fYsGHk5OSQn5/PrFmzmDFjBkuWLCEkJITMzMwyX9qff/6ZNWvWEB4eTm5ubrGv1fr163niiSf46aefiIyMJDMzk9DQUPr27cvXX3/NFVdcwbRp0xg+fHjlTp4BdiRC2npocynUrOfraDyvdjS0H+7rKIwBYGBcfT5fsYMVv++na7NwX4djzjaWjxTyRD5yspLq3Lp1Kw0bNuTrr78G4MCBA2RmZvLFF1+QnJyMiHhkWEn1S6B9pOCyScEfbME3IlXlwQcfZNGiRfj5+bFjxw727NlDgwYNiq1n0aJF3H333QB06NCBDh06FD72ySefMHHiRHJzc9m1axfr168/4fGT/fjjjwwbNoxatWoBcOWVV/LDDz9w+eWX06xZMzp16gRAly5dSElJOeX8ZcuWERUVRdOmTYmJieHGG29k3759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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "f, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n", - "t = f.suptitle('Basic CNN Performance', fontsize=12)\n", - "f.subplots_adjust(top=0.85, wspace=0.3)\n", - "\n", - "epoch_list = list(range(1,31))\n", - "ax1.plot(epoch_list, history.history['acc'], label='Train Accuracy')\n", - "ax1.plot(epoch_list, history.history['val_acc'], label='Validation Accuracy')\n", - "ax1.set_xticks(np.arange(0, 31, 5))\n", - "ax1.set_ylabel('Accuracy Value')\n", - "ax1.set_xlabel('Epoch')\n", - "ax1.set_title('Accuracy')\n", - "l1 = ax1.legend(loc=\"best\")\n", - "\n", - "ax2.plot(epoch_list, history.history['loss'], label='Train Loss')\n", - "ax2.plot(epoch_list, history.history['val_loss'], label='Validation Loss')\n", - "ax2.set_xticks(np.arange(0, 31, 5))\n", - "ax2.set_ylabel('Loss Value')\n", - "ax2.set_xlabel('Epoch')\n", - "ax2.set_title('Loss')\n", - "l2 = ax2.legend(loc=\"best\")\n" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Model: \"sequential_3\"\n", - "_________________________________________________________________\n", - "Layer (type) Output Shape Param # \n", - "=================================================================\n", - "dense_5 (Dense) (None, 256) 1179904 \n", - "_________________________________________________________________\n", - "dropout_2 (Dropout) (None, 256) 0 \n", - "_________________________________________________________________\n", - "dense_6 (Dense) (None, 3) 771 \n", - "=================================================================\n", - "Total params: 1,180,675\n", - "Trainable params: 1,180,675\n", - "Non-trainable params: 0\n", - "_________________________________________________________________\n" - ] - } - ], - "source": [ - "import keras as ks\n", - "model = ks.models.load_model('train3.h5')\n", - "model.summary()" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [], - "source": [ - "#訓練結果提取,建立混淆矩陣\n", - "import pandas as pd\n", - "import tensorflow as tf\n", - "import sklearn\n", - "from sklearn.metrics import confusion_matrix\n", - "predictions = model.predict_classes(test_features)" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 0, 0, 1, 0, 2, 1, 2, 2, 1, 0, 2, 0, 0, 0]\n", - "(15,)\n" - ] - } - ], - "source": [ - "from numpy import argmax\n", - "from keras.utils.np_utils import to_categorical\n", - "test_labels_change = [0]*15\n", - "for i in range(12):\n", - " if(np.array_equal(test_labels[i],[0,0,1])):\n", - " test_labels_change[i] = 2\n", - " elif(np.array_equal(test_labels[i],[0,1,0])):\n", - " test_labels_change[i] = 1\n", - " elif(np.array_equal(test_labels[i],[1,0,0])):\n", - " test_labels_change[i] = 0\n", - "\n", - "print(test_labels_change)\n", - "test_labels_change = np.asarray(test_labels_change)\n", - "print(test_labels_change.shape)" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(15,)\n", - "(15,)\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
預測值012
實際值
0511
1040
2004
\n", - "
" - ], - "text/plain": [ - "預測值 0 1 2\n", - "實際值 \n", - "0 5 1 1\n", - "1 0 4 0\n", - "2 0 0 4" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print(test_labels_change.shape)\n", - "print(predictions.shape)\n", - "pd.crosstab(test_labels_change, predictions, rownames=['實際值'], colnames=['預測值'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.5" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#匯入訓練、驗證、測試圖像\n", + "import os,shutil\n", + "\n", + "base_dir = 'Rec'\n", + "if not os.path.isdir(base_dir):\n", + " os.mkdir(base_dir)\n", + " \n", + "train_dir = os.path.join(base_dir, 'train')\n", + "os.mkdir(train_dir)\n", + "validation_dir = os.path.join(base_dir, 'validation')\n", + "os.mkdir(validation_dir)\n", + "test_dir = os.path.join(base_dir, 'test')\n", + "os.mkdir(test_dir)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#建立訓練集資料夾\n", + "train_b_dir = os.path.join(train_dir, 'be')\n", + "os.mkdir(train_b_dir)\n", + "\n", + "train_h_dir = os.path.join(train_dir, 'ho')\n", + "os.mkdir(train_h_dir)\n", + "\n", + "\n", + "train_y_dir = os.path.join(train_dir, 'yun')\n", + "os.mkdir(train_y_dir)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "#建立驗證集資料夾\n", + "validation_b_dir = os.path.join(validation_dir, 'be')\n", + "os.mkdir(validation_b_dir)\n", + "\n", + "validation_h_dir = os.path.join(validation_dir, 'ho')\n", + "os.mkdir(validation_h_dir)\n", + "\n", + "validation_y_dir = os.path.join(validation_dir, 'yun')\n", + "os.mkdir(validation_y_dir)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "#建立測試集資料夾\n", + "test_b_dir = os.path.join(test_dir, 'be')\n", + "os.mkdir(test_b_dir)\n", + "\n", + "test_h_dir = os.path.join(test_dir, 'ho')\n", + "os.mkdir(test_h_dir)\n", + "\n", + "test_y_dir = os.path.join(test_dir, 'yun')\n", + "os.mkdir(test_y_dir)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "#擷取be資料集的圖片範圍\n", + "original_0dataset_dir = 'be'\n", + "fnames = ['be.{}.png'.format(i) for i in range(20)]\n", + "for fname in fnames:\n", + " src = os.path.join(original_0dataset_dir, fname)\n", + " dst = os.path.join(train_b_dir, fname)\n", + " shutil.copyfile(src, dst)\n", + "\n", + "fnames = ['be.{}.png'.format(i) for i in range(45, 54)]\n", + "for fname in fnames:\n", + " src = os.path.join(original_0dataset_dir, fname)\n", + " dst = os.path.join(validation_b_dir, fname)\n", + " shutil.copyfile(src, dst)\n", + "\n", + "fnames = ['be.{}.png'.format(i) for i in range(54, 59)]\n", + "for fname in fnames:\n", + " src = os.path.join(original_0dataset_dir, fname)\n", + " dst = os.path.join(test_b_dir, fname)\n", + " shutil.copyfile(src, dst)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "#擷取ho資料集的圖片範圍\n", + "original_0dataset_dir = 'ho'\n", + "fnames = ['ho.{}.png'.format(i) for i in range(20)]\n", + "for fname in fnames:\n", + " src = os.path.join(original_0dataset_dir, fname)\n", + " dst = os.path.join(train_h_dir, fname)\n", + " shutil.copyfile(src, dst)\n", + "\n", + "fnames = ['ho.{}.png'.format(i) for i in range(45, 54)]\n", + "for fname in fnames:\n", + " src = os.path.join(original_0dataset_dir, fname)\n", + " dst = os.path.join(validation_h_dir, fname)\n", + " shutil.copyfile(src, dst)\n", + "\n", + "fnames = ['ho.{}.png'.format(i) for i in range(54, 59)]\n", + "for fname in fnames:\n", + " src = os.path.join(original_0dataset_dir, fname)\n", + " dst = os.path.join(test_h_dir, fname)\n", + " shutil.copyfile(src, dst)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "#擷取yun資料集的圖片範圍\n", + "original_0dataset_dir = 'yun'\n", + "fnames = ['yun.{}.png'.format(i) for i in range(20)]\n", + "for fname in fnames:\n", + " src = os.path.join(original_0dataset_dir, fname)\n", + " dst = os.path.join(train_y_dir, fname)\n", + " shutil.copyfile(src, dst)\n", + "\n", + "fnames = ['yun.{}.png'.format(i) for i in range(45, 54)]\n", + "for fname in fnames:\n", + " src = os.path.join(original_0dataset_dir, fname)\n", + " dst = os.path.join(validation_y_dir, fname)\n", + " shutil.copyfile(src, dst)\n", + "\n", + "fnames = ['yun.{}.png'.format(i) for i in range(54, 59)]\n", + "for fname in fnames:\n", + " src = os.path.join(original_0dataset_dir, fname)\n", + " dst = os.path.join(test_y_dir, fname)\n", + " shutil.copyfile(src, dst)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(test_y_dir)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model: \"sequential_1\"\n", + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "conv2d_1 (Conv2D) (None, 98, 98, 32) 896 \n", + "_________________________________________________________________\n", + "max_pooling2d_1 (MaxPooling2 (None, 49, 49, 32) 0 \n", + "_________________________________________________________________\n", + "conv2d_2 (Conv2D) (None, 47, 47, 64) 18496 \n", + "_________________________________________________________________\n", + "max_pooling2d_2 (MaxPooling2 (None, 23, 23, 64) 0 \n", + "_________________________________________________________________\n", + "conv2d_3 (Conv2D) (None, 21, 21, 128) 73856 \n", + "_________________________________________________________________\n", + "max_pooling2d_3 (MaxPooling2 (None, 10, 10, 128) 0 \n", + "_________________________________________________________________\n", + "conv2d_4 (Conv2D) (None, 8, 8, 128) 147584 \n", + "_________________________________________________________________\n", + "max_pooling2d_4 (MaxPooling2 (None, 4, 4, 128) 0 \n", + "_________________________________________________________________\n", + "flatten_1 (Flatten) (None, 2048) 0 \n", + "_________________________________________________________________\n", + "dense_1 (Dense) (None, 512) 1049088 \n", + "_________________________________________________________________\n", + "dense_2 (Dense) (None, 3) 1539 \n", + "=================================================================\n", + "Total params: 1,291,459\n", + "Trainable params: 1,291,459\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ], + "source": [ + "#建立cnn\n", + "from keras import layers\n", + "from keras import models\n", + "\n", + "model = models.Sequential()\n", + "model.add(layers.Conv2D(32, (3, 3), activation='relu',\n", + " input_shape=(100, 100, 3)))\n", + "model.add(layers.MaxPooling2D((2, 2)))\n", + "model.add(layers.Conv2D(64, (3, 3), activation='relu'))\n", + "model.add(layers.MaxPooling2D((2, 2)))\n", + "model.add(layers.Conv2D(128, (3, 3), activation='relu'))\n", + "model.add(layers.MaxPooling2D((2, 2)))\n", + "model.add(layers.Conv2D(128, (3, 3), activation='relu'))\n", + "model.add(layers.MaxPooling2D((2, 2)))\n", + "model.add(layers.Flatten())\n", + "model.add(layers.Dense(512, activation='relu'))\n", + "model.add(layers.Dense(3, activation='softmax'))\n", + "\n", + "model.summary()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "#優化器\n", + "from keras import optimizers\n", + "\n", + "model.compile(loss='categorical_crossentropy',\n", + " optimizer=optimizers.RMSprop(lr=1e-4),\n", + " metrics=['acc'])" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found 60 images belonging to 3 classes.\n", + "Found 27 images belonging to 3 classes.\n" + ] + } + ], + "source": [ + "#ImageDataGenerator套件label圖片\n", + "from keras.preprocessing.image import ImageDataGenerator\n", + "import numpy as np\n", + "train_datagen = ImageDataGenerator(rescale=1./255)\n", + "test_datagen = ImageDataGenerator(rescale=1./255)\n", + "\n", + "train_generator = train_datagen.flow_from_directory(\n", + " train_dir,\n", + " target_size=(100, 100),\n", + " batch_size=20,\n", + " class_mode='categorical')\n", + "\n", + "validation_generator = test_datagen.flow_from_directory(\n", + " validation_dir,\n", + " target_size=(100, 100),\n", + " batch_size=20,\n", + " class_mode='categorical')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "data batch shape: (20, 100, 100, 3)\n", + "labels batch shape: (20, 3)\n" + ] + } + ], + "source": [ + "for data_batch, labels_batch in train_generator:\n", + " print('data batch shape:', data_batch.shape)\n", + " print('labels batch shape:', labels_batch.shape)\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/30\n", + "100/100 [==============================] - 94s 940ms/step - loss: 0.6316 - acc: 0.7760 - val_loss: 0.8940 - val_acc: 0.7778\n", + "Epoch 2/30\n", + "100/100 [==============================] - 93s 930ms/step - loss: 0.4135 - acc: 0.8530 - val_loss: 0.6577 - val_acc: 0.7037\n", + "Epoch 3/30\n", + "100/100 [==============================] - 94s 941ms/step - loss: 0.2813 - acc: 0.8860 - val_loss: 0.6228 - val_acc: 0.6296\n", + "Epoch 4/30\n", + "100/100 [==============================] - 93s 933ms/step - loss: 0.1676 - acc: 0.9280 - val_loss: 1.7445 - val_acc: 0.5926\n", + "Epoch 5/30\n", + "100/100 [==============================] - 94s 939ms/step - loss: 0.1259 - acc: 0.9370 - val_loss: 1.0945 - val_acc: 0.5926\n", + "Epoch 6/30\n", + "100/100 [==============================] - 94s 942ms/step - loss: 0.1062 - acc: 0.9405 - val_loss: 2.6368 - val_acc: 0.5926\n", + "Epoch 7/30\n", + "100/100 [==============================] - 96s 960ms/step - loss: 0.0993 - acc: 0.9390 - val_loss: 1.2031 - val_acc: 0.5926\n", + "Epoch 8/30\n", + "100/100 [==============================] - 95s 954ms/step - loss: 0.0951 - acc: 0.9305 - val_loss: 2.8705 - val_acc: 0.5926\n", + "Epoch 9/30\n", + "100/100 [==============================] - 96s 957ms/step - loss: 0.0892 - acc: 0.9385 - val_loss: 2.4154 - val_acc: 0.5926\n", + "Epoch 10/30\n", + "100/100 [==============================] - 97s 966ms/step - loss: 0.0860 - acc: 0.9365 - val_loss: 4.6667 - val_acc: 0.5926\n", + "Epoch 11/30\n", + "100/100 [==============================] - 97s 970ms/step - loss: 0.0860 - acc: 0.9365 - val_loss: 2.0964 - val_acc: 0.5926\n", + "Epoch 12/30\n", + "100/100 [==============================] - 97s 973ms/step - loss: 0.0844 - acc: 0.9365 - val_loss: 4.6467 - val_acc: 0.5926\n", + "Epoch 13/30\n", + "100/100 [==============================] - 97s 969ms/step - loss: 0.0842 - acc: 0.9365 - val_loss: 0.8492 - val_acc: 0.5926\n", + "Epoch 14/30\n", + "100/100 [==============================] - 97s 972ms/step - loss: 0.0811 - acc: 0.9345 - val_loss: 6.7441 - val_acc: 0.5926\n", + "Epoch 15/30\n", + "100/100 [==============================] - 97s 971ms/step - loss: 0.0801 - acc: 0.9380 - val_loss: 1.3565 - val_acc: 0.5926\n", + "Epoch 16/30\n", + "100/100 [==============================] - 97s 973ms/step - loss: 0.0775 - acc: 0.9315 - val_loss: 5.6226 - val_acc: 0.5926\n", + "Epoch 17/30\n", + "100/100 [==============================] - 98s 983ms/step - loss: 0.0816 - acc: 0.9315 - val_loss: 5.0703 - val_acc: 0.5926\n", + "Epoch 18/30\n", + "100/100 [==============================] - 98s 984ms/step - loss: 0.0746 - acc: 0.9330 - val_loss: 7.8723 - val_acc: 0.5926\n", + "Epoch 19/30\n", + "100/100 [==============================] - 98s 983ms/step - loss: 0.0747 - acc: 0.9360 - val_loss: 2.2070 - val_acc: 0.5926\n", + "Epoch 20/30\n", + "100/100 [==============================] - 98s 979ms/step - loss: 0.0756 - acc: 0.9320 - val_loss: 8.8935 - val_acc: 0.5926\n", + "Epoch 21/30\n", + "100/100 [==============================] - 98s 983ms/step - loss: 0.0775 - acc: 0.9350 - val_loss: 2.1388 - val_acc: 0.5926\n", + "Epoch 22/30\n", + "100/100 [==============================] - 98s 984ms/step - loss: 0.0734 - acc: 0.9360 - val_loss: 4.9511 - val_acc: 0.5926\n", + "Epoch 23/30\n", + "100/100 [==============================] - 98s 982ms/step - loss: 0.0729 - acc: 0.9335 - val_loss: 1.6979 - val_acc: 0.5926\n", + "Epoch 24/30\n", + "100/100 [==============================] - 99s 988ms/step - loss: 0.0718 - acc: 0.9325 - val_loss: 3.6615 - val_acc: 0.5926\n", + "Epoch 25/30\n", + "100/100 [==============================] - 98s 983ms/step - loss: 0.0729 - acc: 0.9375 - val_loss: 6.6448 - val_acc: 0.5926\n", + "Epoch 26/30\n", + "100/100 [==============================] - 98s 984ms/step - loss: 0.0721 - acc: 0.9355 - val_loss: 6.3982 - val_acc: 0.5926\n", + "Epoch 27/30\n", + "100/100 [==============================] - 98s 980ms/step - loss: 0.0711 - acc: 0.9340 - val_loss: 12.2808 - val_acc: 0.5926\n", + "Epoch 28/30\n", + "100/100 [==============================] - 98s 980ms/step - loss: 0.0721 - acc: 0.9365 - val_loss: 7.8047 - val_acc: 0.5926\n", + "Epoch 29/30\n", + "100/100 [==============================] - 98s 980ms/step - loss: 0.0704 - acc: 0.9310 - val_loss: 9.7293 - val_acc: 0.5926\n", + "Epoch 30/30\n", + "100/100 [==============================] - 98s 982ms/step - loss: 0.0737 - acc: 0.9360 - val_loss: 6.4731 - val_acc: 0.5926\n" + ] + } + ], + "source": [ + "#epoch訓練30\n", + "history = model.fit_generator(\n", + " train_generator,\n", + " steps_per_epoch=100,\n", + " epochs=30,\n", + " validation_data=validation_generator,\n", + " validation_steps=50)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "model.save('train1.h5')" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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OHK8lOMlZRwvLStfdr4mcRHB5atudnAk3MnxEbSLDScsOJDgQCEkMICgwACCA4XggIA6T+r0Bk2uG8HEiRO59NJLmTVrVvm2a665hksuuYT09HT69u1Lt241d3647bbbuP766+nduzd9+/Zl4MCBgG2H169fP3r27EmnTp0YOnRo+TE333wzo0ePpm3btsybN698e//+/Zk8eXL5OW688Ub69etXZQlIZfPnz6d9+/bliTXYZD0jI4Ndu3bx1ltvccstt/Dggw8SHBzMe++9x6hRo1i1ahXp6emEhIRw4YUX8re//Y177rmHK664grfeeotzzz232tes7r3q2bMn999/P2effTaBgYH069eP119/vfyYBx54oMIfNH4vNhmCwqCkUNvwKaWUahStY8IY1avqktWalJYZm2iXlFFUWlr+dUFRCdkHjrF9/1F27D/K9v1HycjJ56u1uykurT0hDwwQggOF0KBAUltG0LlVFGmtoklrFUVa6yiS4ry/fL3UVCLgT9LT082KFSsqbFu3bh3du3f3UkTKm95//30+/vjjGkfk/fL746VhkLcJ/pQDAYHejkZVQ0RWGmOqb0Kv6q2qa71Syv+Vlhn25Beyff9Rdh8qLB8BLy4to6TUlH9tb4ajx0vIzDvKpr2H2ZNfVH6eUEcHlrRWUXROjEIEO8pePupeXPFxUQlXnZHM1NF1a29b03VeR65Vk/Pb3/6WOXPmNGhfb5/R8WyIaqOJtVJKqSYlMEBoFxtOu9iT2//WJr+wmM17C9i8p4BNew+zaW8BK7PsIj0AYcEBRIUGExMWVF4vnhwfQVRYENGO1TkbkibXqsn597//7e0QPOeCx7wdgVJKKeVTYsKC6Z8cR//kuArbC4tLHWUkAY0ajybXSimllFKqyQkL9s6nvI2byntBU6kpVw1Lvy+UUkop5QlNOrkOCwtj3759mkipCowx7Nu3r3yRG6WUUkqphtKky0KSkpLIzs4mNzfX26EoHxMWFkZSUpK3w1CqSRORUcA/gUDgVWPM45Wevxu4ESgBcoEbjDE1N/1XSikf59Hk2o0L62TgSWCnY9NzxphXHc9dBzzg2P6oMeaNur5+cHAwHTt2rGf0Siml6ktEAoHngZFANrBcRGYbYzJcdvsJSDfGHBWR24AngCsbP1qllGo4Hkuu3bywArxrjJlS6dh44C9AOmCA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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "#可視化結果\n", + "f, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n", + "t = f.suptitle('Basic CNN Performance', fontsize=12)\n", + "f.subplots_adjust(top=0.85, wspace=0.3)\n", + "\n", + "epoch_list = list(range(1,31))\n", + "ax1.plot(epoch_list, history.history['acc'], label='Train Accuracy')\n", + "ax1.plot(epoch_list, history.history['val_acc'], label='Validation Accuracy')\n", + "ax1.set_xticks(np.arange(0, 31, 5))\n", + "ax1.set_ylabel('Accuracy Value')\n", + "ax1.set_xlabel('Epoch')\n", + "ax1.set_title('Accuracy')\n", + "l1 = ax1.legend(loc=\"best\")\n", + "\n", + "ax2.plot(epoch_list, history.history['loss'], label='Train Loss')\n", + "ax2.plot(epoch_list, history.history['val_loss'], label='Validation Loss')\n", + "ax2.set_xticks(np.arange(0, 31, 5))\n", + "ax2.set_ylabel('Loss Value')\n", + "ax2.set_xlabel('Epoch')\n", + "ax2.set_title('Loss')\n", + "l2 = ax2.legend(loc=\"best\")" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model: \"sequential_2\"\n", + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "conv2d_5 (Conv2D) (None, 98, 98, 32) 896 \n", + "_________________________________________________________________\n", + "max_pooling2d_5 (MaxPooling2 (None, 49, 49, 32) 0 \n", + "_________________________________________________________________\n", + "conv2d_6 (Conv2D) (None, 47, 47, 64) 18496 \n", + "_________________________________________________________________\n", + "max_pooling2d_6 (MaxPooling2 (None, 23, 23, 64) 0 \n", + "_________________________________________________________________\n", + "conv2d_7 (Conv2D) (None, 21, 21, 128) 73856 \n", + "_________________________________________________________________\n", + "max_pooling2d_7 (MaxPooling2 (None, 10, 10, 128) 0 \n", + "_________________________________________________________________\n", + "conv2d_8 (Conv2D) (None, 8, 8, 128) 147584 \n", + "_________________________________________________________________\n", + "max_pooling2d_8 (MaxPooling2 (None, 4, 4, 128) 0 \n", + "_________________________________________________________________\n", + "flatten_2 (Flatten) (None, 2048) 0 \n", + "_________________________________________________________________\n", + "dropout_1 (Dropout) (None, 2048) 0 \n", + "_________________________________________________________________\n", + "dense_3 (Dense) (None, 512) 1049088 \n", + "_________________________________________________________________\n", + "dense_4 (Dense) (None, 3) 1539 \n", + "=================================================================\n", + "Total params: 1,291,459\n", + "Trainable params: 1,291,459\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ], + "source": [ + "#套入VGG16模型\n", + "from keras.applications import VGG16\n", + "\n", + "\n", + "conv_base = VGG16(weights='imagenet',\n", + " include_top=False,\n", + " input_shape=(100,100, 3))\n", + "model.summary()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found 60 images belonging to 3 classes.\n", + "[[1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [1. 0. 0.]\n", + " [0. 1. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [0. 1. 0.]\n", + " [1. 0. 0.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [1. 0. 0.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]]\n", + "[[0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [0. 1. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [0. 1. 0.]]\n", + "[[0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [0. 1. 0.]\n", + " [0. 1. 0.]\n", + " [1. 0. 0.]\n", + " [0. 1. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [0. 0. 1.]]\n", + "Found 27 images belonging to 3 classes.\n", + "[[0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [1. 0. 0.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [1. 0. 0.]\n", + " [0. 1. 0.]\n", + " [0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [1. 0. 0.]\n", + " [0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [0. 1. 0.]]\n", + "Found 15 images belonging to 3 classes.\n", + "[[0. 1. 0.]\n", + " [1. 0. 0.]\n", + " [1. 0. 0.]\n", + " [0. 1. 0.]\n", + " [1. 0. 0.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [1. 0. 0.]\n", + " [0. 0. 1.]\n", + " [0. 0. 1.]\n", + " [0. 1. 0.]\n", + " [1. 0. 0.]]\n" + ] + } + ], + "source": [ + "#使用conv_base的模型先抽取特徵跟label產出,將特徵提取後進行降維輸出\n", + "import os\n", + "import numpy as np\n", + "from keras.preprocessing.image import ImageDataGenerator\n", + "\n", + "base_dir = 'Rec'\n", + "\n", + "train_dir = os.path.join(base_dir, 'train')\n", + "validation_dir = os.path.join(base_dir, 'validation')\n", + "test_dir = os.path.join(base_dir, 'test')\n", + "\n", + "datagen = ImageDataGenerator(rescale=1./255)\n", + "batch_size = 20\n", + "\n", + "def extract_features(directory, sample_count):\n", + " features = np.zeros(shape=(sample_count, 3, 3, 512))\n", + " labels = np.zeros(shape=(sample_count,3))\n", + " generator = datagen.flow_from_directory(\n", + " directory,\n", + " target_size=(100, 100),\n", + " batch_size=batch_size,\n", + " class_mode='categorical'\n", + " )\n", + " i = 0\n", + " for inputs_batch, labels_batch in generator:\n", + " features_batch = conv_base.predict(inputs_batch)\n", + " features[i * batch_size : (i + 1) * batch_size] = features_batch\n", + " print(labels_batch)\n", + " labels[i * batch_size : (i + 1) * batch_size] = labels_batch\n", + " i += 1\n", + " if i * batch_size >= sample_count:\n", + " \n", + " break\n", + " return features, labels\n", + "\n", + "train_features, train_labels = extract_features(train_dir, 60)\n", + "validation_features, validation_labels = extract_features(validation_dir, 20)\n", + "test_features, test_labels = extract_features(test_dir, 15)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "train_features = np.resize(train_features, (60, 3 * 3 * 512))\n", + "validation_features = np.resize(validation_features, (20, 3 * 3 * 512))\n", + "test_features = np.resize(test_features, (15, 3 * 3 * 512))" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train on 60 samples, validate on 20 samples\n", + "Epoch 1/30\n", + "60/60 [==============================] - 1s 10ms/step - loss: 2.0313 - acc: 0.3167 - val_loss: 1.8868 - val_acc: 0.3000\n", + "Epoch 2/30\n", + "60/60 [==============================] - 0s 483us/step - loss: 1.8181 - acc: 0.3333 - val_loss: 1.7381 - val_acc: 0.3000\n", + "Epoch 3/30\n", + "60/60 [==============================] - 0s 566us/step - loss: 1.6853 - acc: 0.3000 - val_loss: 1.6217 - val_acc: 0.3000\n", + "Epoch 4/30\n", + "60/60 [==============================] - 0s 550us/step - loss: 1.6355 - acc: 0.3167 - val_loss: 1.5229 - val_acc: 0.3000\n", + "Epoch 5/30\n", + "60/60 [==============================] - 0s 483us/step - loss: 1.5393 - acc: 0.3333 - val_loss: 1.4473 - val_acc: 0.3000\n", + "Epoch 6/30\n", + "60/60 [==============================] - 0s 550us/step - loss: 1.5782 - acc: 0.2833 - val_loss: 1.3734 - val_acc: 0.3000\n", + "Epoch 7/30\n", + "60/60 [==============================] - 0s 533us/step - loss: 1.4986 - acc: 0.2833 - val_loss: 1.3062 - val_acc: 0.3000\n", + "Epoch 8/30\n", + "60/60 [==============================] - 0s 500us/step - loss: 1.4321 - acc: 0.3667 - val_loss: 1.2484 - val_acc: 0.3000\n", + "Epoch 9/30\n", + "60/60 [==============================] - 0s 583us/step - loss: 1.3253 - acc: 0.3333 - val_loss: 1.1981 - val_acc: 0.3000\n", + "Epoch 10/30\n", + "60/60 [==============================] - 0s 566us/step - loss: 1.2468 - acc: 0.4167 - val_loss: 1.1543 - val_acc: 0.3000\n", + "Epoch 11/30\n", + "60/60 [==============================] - 0s 566us/step - loss: 1.1066 - acc: 0.4500 - val_loss: 1.1124 - val_acc: 0.3000\n", + "Epoch 12/30\n", + "60/60 [==============================] - 0s 600us/step - loss: 1.2571 - acc: 0.3333 - val_loss: 1.0764 - val_acc: 0.3000\n", + "Epoch 13/30\n", + "60/60 [==============================] - 0s 566us/step - loss: 1.1691 - acc: 0.4667 - val_loss: 1.0375 - val_acc: 0.3500\n", + "Epoch 14/30\n", + "60/60 [==============================] - 0s 550us/step - loss: 1.1005 - acc: 0.5167 - val_loss: 1.0097 - val_acc: 0.3500\n", + "Epoch 15/30\n", + "60/60 [==============================] - 0s 566us/step - loss: 1.1293 - acc: 0.4167 - val_loss: 0.9818 - val_acc: 0.4000\n", + "Epoch 16/30\n", + "60/60 [==============================] - 0s 516us/step - loss: 1.1421 - acc: 0.4167 - val_loss: 0.9571 - val_acc: 0.4000\n", + "Epoch 17/30\n", + "60/60 [==============================] - 0s 533us/step - loss: 1.0784 - acc: 0.5000 - val_loss: 0.9312 - val_acc: 0.5500\n", + "Epoch 18/30\n", + "60/60 [==============================] - 0s 516us/step - loss: 1.0378 - acc: 0.4500 - val_loss: 0.9119 - val_acc: 0.6000\n", + "Epoch 19/30\n", + "60/60 [==============================] - 0s 533us/step - loss: 0.9446 - acc: 0.5000 - val_loss: 0.8883 - val_acc: 0.7500\n", + "Epoch 20/30\n", + "60/60 [==============================] - 0s 533us/step - loss: 0.9756 - acc: 0.5167 - val_loss: 0.8679 - val_acc: 0.7500\n", + "Epoch 21/30\n", + "60/60 [==============================] - 0s 633us/step - loss: 0.9451 - acc: 0.5667 - val_loss: 0.8540 - val_acc: 0.7500\n", + "Epoch 22/30\n", + "60/60 [==============================] - 0s 566us/step - loss: 0.7960 - acc: 0.6500 - val_loss: 0.8393 - val_acc: 0.7500\n", + "Epoch 23/30\n", + "60/60 [==============================] - 0s 566us/step - loss: 0.8670 - acc: 0.5833 - val_loss: 0.8223 - val_acc: 0.7500\n", + "Epoch 24/30\n", + "60/60 [==============================] - 0s 600us/step - loss: 0.9493 - acc: 0.6167 - val_loss: 0.8102 - val_acc: 0.7500\n", + "Epoch 25/30\n", + "60/60 [==============================] - 0s 566us/step - loss: 0.9749 - acc: 0.5500 - val_loss: 0.7922 - val_acc: 0.7500\n", + "Epoch 26/30\n", + "60/60 [==============================] - 0s 583us/step - loss: 0.9339 - acc: 0.6333 - val_loss: 0.7809 - val_acc: 0.8000\n", + "Epoch 27/30\n", + "60/60 [==============================] - 0s 550us/step - loss: 0.7419 - acc: 0.7000 - val_loss: 0.7721 - val_acc: 0.8000\n", + "Epoch 28/30\n", + "60/60 [==============================] - 0s 583us/step - loss: 0.8690 - acc: 0.6167 - val_loss: 0.7634 - val_acc: 0.8000\n", + "Epoch 29/30\n", + "60/60 [==============================] - 0s 583us/step - loss: 0.8348 - acc: 0.6167 - val_loss: 0.7556 - val_acc: 0.8000\n", + "Epoch 30/30\n", + "60/60 [==============================] - 0s 533us/step - loss: 0.7058 - acc: 0.7000 - val_loss: 0.7460 - val_acc: 0.8000\n" + ] + } + ], + "source": [ + "#建立優化防止梯度下降訓練\n", + "from keras import models\n", + "from keras import layers\n", + "from keras import optimizers\n", + "\n", + "model = models.Sequential()\n", + "model.add(layers.Dense(256, activation='relu', input_dim=3 * 3 * 512))\n", + "model.add(layers.Dropout(0.5))\n", + "model.add(layers.Dense(3, activation='softmax'))\n", + "\n", + "model.compile(optimizer=optimizers.RMSprop(lr=2e-5),\n", + " loss='categorical_crossentropy',\n", + " metrics=['acc'])\n", + "\n", + "history = model.fit(train_features, train_labels,\n", + " epochs=30,\n", + " batch_size=100,\n", + " validation_data=(validation_features, validation_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "model.save('train3.h5')" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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Xhw6dIihQ4eyb98+jh8/zuOPP87QoScu65WSksKll17K2rVrOXLkCGPHjmX9+vXExcVx5MiRwnK33347y5Yt48iRI4wYMYJHH32UV155hZ07d9KvXz8iIyOZP38+sbGxLF++nMjISF544QUmTZoEwLhx4/jzn/9MSkoKgwcPplevXixevJhGjRrx5ZdfUrNmzVOe20cffcS1115LUlISM2fOLPxPuHnzZm677TbS09Px9/fn008/pXnz5jzzzDN88MEH+Pn5MXjwYJ566in69u3Lc889R0JCAnv37iUhIYGUlBTeffddvv76a3JycsjOzmbmzJklvlbvv/8+zz33HCJChw4d+M9//kOHDh3YuHEjgYGBZGVl0aFDBzZt2kRgYKC3ftVn7nAmvDsEjnjuCkGloXlwaA9c+Zb1Phuf8/cT+raOYm5SGrl5+QTYroTmLFCd85HiFFdndnY2V111FampqeTl5fHPf/6Tq6++mvHjxzNz5kwCAgIYNGjQGfdoV78EetZ42P2rZ+tscB4MfqrEhyMiIujatSvffvstQ4cOZdq0aVx99dWICMHBwXzxxReEhYWxd+9eunfvzuWXX46zOdepXn/9dUJCQlizZg1r1qwhPj6+8LEnnniC8PBw8vLyGDBgAGvWrOHuu+/mhRdeYP78+URGRp5QV2JiIpMnT2bJkiWoKt26daNPnz7Uq1ePTZs2MXXqVN566y2uuuoqpk+fzpgxY06J5+OPP+b7779nw4YNTJgwoTCBHj16NOPHj2fYsGHk5OSQn5/PrFmzmDFjBkuWLCEkJITMzMwyX9qff/6ZNWvWEB4eTm5ubrGv1fr163niiSf46aefiIyMJDMzk9DQUPr27cvXX3/NFVdcwbRp0xg+fHjlTp4BdiRC2npocynUrOfraDyvdjS0H+7rKIwBYGBcfT5fsYMVv++na7NwX4djzjaWjxTyRD5yspLq3Lp1Kw0bNuTrr78G4MCBA2RmZvLFF1+QnJyMiHhkWEn1S6B9pOCyScEfbME3IlXlwQcfZNGiRfj5+bFjxw727NlDgwYNiq1n0aJF3H333QB06NCBDh06FD72ySefMHHiRHJzc9m1axfr168/4fGT/fjjjwwbNoxatWoBcOWVV/LDDz9w+eWX06xZMzp16gRAly5dSElJOeX8ZcuWERUVRdOmTYmJieHGG29k3759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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "f, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n", + "t = f.suptitle('Basic CNN Performance', fontsize=12)\n", + "f.subplots_adjust(top=0.85, wspace=0.3)\n", + "\n", + "epoch_list = list(range(1,31))\n", + "ax1.plot(epoch_list, history.history['acc'], label='Train Accuracy')\n", + "ax1.plot(epoch_list, history.history['val_acc'], label='Validation Accuracy')\n", + "ax1.set_xticks(np.arange(0, 31, 5))\n", + "ax1.set_ylabel('Accuracy Value')\n", + "ax1.set_xlabel('Epoch')\n", + "ax1.set_title('Accuracy')\n", + "l1 = ax1.legend(loc=\"best\")\n", + "\n", + "ax2.plot(epoch_list, history.history['loss'], label='Train Loss')\n", + "ax2.plot(epoch_list, history.history['val_loss'], label='Validation Loss')\n", + "ax2.set_xticks(np.arange(0, 31, 5))\n", + "ax2.set_ylabel('Loss Value')\n", + "ax2.set_xlabel('Epoch')\n", + "ax2.set_title('Loss')\n", + "l2 = ax2.legend(loc=\"best\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model: \"sequential_3\"\n", + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "dense_5 (Dense) (None, 256) 1179904 \n", + "_________________________________________________________________\n", + "dropout_2 (Dropout) (None, 256) 0 \n", + "_________________________________________________________________\n", + "dense_6 (Dense) (None, 3) 771 \n", + "=================================================================\n", + "Total params: 1,180,675\n", + "Trainable params: 1,180,675\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ], + "source": [ + "import keras as ks\n", + "model = ks.models.load_model('train3.h5')\n", + "model.summary()" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "#訓練結果提取,建立混淆矩陣\n", + "import pandas as pd\n", + "import tensorflow as tf\n", + "import sklearn\n", + "from sklearn.metrics import confusion_matrix\n", + "predictions = model.predict_classes(test_features)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 0, 0, 1, 0, 2, 1, 2, 2, 1, 0, 2, 0, 0, 0]\n", + "(15,)\n" + ] + } + ], + "source": [ + "from numpy import argmax\n", + "from keras.utils.np_utils import to_categorical\n", + "test_labels_change = [0]*15\n", + "for i in range(12):\n", + " if(np.array_equal(test_labels[i],[0,0,1])):\n", + " test_labels_change[i] = 2\n", + " elif(np.array_equal(test_labels[i],[0,1,0])):\n", + " test_labels_change[i] = 1\n", + " elif(np.array_equal(test_labels[i],[1,0,0])):\n", + " test_labels_change[i] = 0\n", + "\n", + "print(test_labels_change)\n", + "test_labels_change = np.asarray(test_labels_change)\n", + "print(test_labels_change.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(15,)\n", + "(15,)\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
預測值012
實際值
0511
1040
2004
\n", + "
" + ], + "text/plain": [ + "預測值 0 1 2\n", + "實際值 \n", + "0 5 1 1\n", + "1 0 4 0\n", + "2 0 0 4" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(test_labels_change.shape)\n", + "print(predictions.shape)\n", + "pd.crosstab(test_labels_change, predictions, rownames=['實際值'], colnames=['預測值'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Facial-Keypoint-Detection/Readme.md b/Facial-Keypoint-Detection/Readme.md index 62d7a2358..c7ab91f8a 100644 --- a/Facial-Keypoint-Detection/Readme.md +++ b/Facial-Keypoint-Detection/Readme.md @@ -1,43 +1,43 @@ -# Objective -Here we convert the https://www.kaggle.com/competitions/facial-keypoints-detection code to kfp-pipeline -The objective of this task is to predict keypoint positions on face images - -# Testing enviornment -The pipeline is tested on `Kubeflow 1.4` and `kfp 1.1.2` , it should be compatible with previous releases of Kubeflow . kfp version used for testing is 1.1.2 which can be installed as `pip install kfp==1.1.2` - -# Components used - -## Docker -Docker is used to create an enviornment to run each component. - -## Kubeflow pipelines -Kubeflow pipelines connect each docker component and create a pipeline. Each Kubeflow pipeline is reproducable workflow wherein we pass input arguments and run entire workflow. - -# Docker -We start with creating a docker account on dockerhub (https://hub.docker.com/). We signup with our individual email. After signup is compelete login to docker using your username and password using the command `docker login` on your terminal - -## Build train image -Navigate to `train` directory, create a folder named `my_data` and put your `training.zip` and `test.zip` data from Kaggle repo in this folder and build docker image using : -``` -docker build -t /: . -``` -In my case this is: -``` -docker build -t hubdocker76/demotrain:v1 . -``` - -## Build evaluate image -Navigate to eval directory and build docker image using : -``` -docker build -t /: . -``` -In my case this is: -``` -docker build -t hubdocker76/demoeval:v2 . -``` -# Kubeflow pipelines - -Go to generate-pipeline and run `python3 my_pipeline.py` this will generate a yaml file. which we can upload to Kubeflow pipelines UI and create a Run from it. - -# Sample pipeline to run on Kubeflow -Navigate to directory `geneate-pipeline` and run `python3 my_pipeline.py` this will generate yaml file. I have named this yaml as `face_pipeline_01.yaml`. Please upload this pipeline on Kubeflow and start a Run. +# Objective +Here we convert the https://www.kaggle.com/competitions/facial-keypoints-detection code to kfp-pipeline +The objective of this task is to predict keypoint positions on face images + +# Testing enviornment +The pipeline is tested on `Kubeflow 1.4` and `kfp 1.1.2` , it should be compatible with previous releases of Kubeflow . kfp version used for testing is 1.1.2 which can be installed as `pip install kfp==1.1.2` + +# Components used + +## Docker +Docker is used to create an enviornment to run each component. + +## Kubeflow pipelines +Kubeflow pipelines connect each docker component and create a pipeline. Each Kubeflow pipeline is reproducable workflow wherein we pass input arguments and run entire workflow. + +# Docker +We start with creating a docker account on dockerhub (https://hub.docker.com/). We signup with our individual email. After signup is compelete login to docker using your username and password using the command `docker login` on your terminal + +## Build train image +Navigate to `train` directory, create a folder named `my_data` and put your `training.zip` and `test.zip` data from Kaggle repo in this folder and build docker image using : +``` +docker build -t /: . +``` +In my case this is: +``` +docker build -t hubdocker76/demotrain:v1 . +``` + +## Build evaluate image +Navigate to eval directory and build docker image using : +``` +docker build -t /: . +``` +In my case this is: +``` +docker build -t hubdocker76/demoeval:v2 . +``` +# Kubeflow pipelines + +Go to generate-pipeline and run `python3 my_pipeline.py` this will generate a yaml file. which we can upload to Kubeflow pipelines UI and create a Run from it. + +# Sample pipeline to run on Kubeflow +Navigate to directory `geneate-pipeline` and run `python3 my_pipeline.py` this will generate yaml file. I have named this yaml as `face_pipeline_01.yaml`. Please upload this pipeline on Kubeflow and start a Run. diff --git a/Facial-Keypoint-Detection/generate-pipeline/my_pipeline.py b/Facial-Keypoint-Detection/generate-pipeline/my_pipeline.py index 9ec0ee6e5..39ca3e21d 100644 --- a/Facial-Keypoint-Detection/generate-pipeline/my_pipeline.py +++ b/Facial-Keypoint-Detection/generate-pipeline/my_pipeline.py @@ -1,42 +1,42 @@ -import kfp -from kfp import dsl - -def SendMsg(trial, epoch, patience): - vop = dsl.VolumeOp(name="pvc", - resource_name="pvc", size='1Gi', - modes=dsl.VOLUME_MODE_RWO) - - return dsl.ContainerOp( - name = 'Train', - image = 'hubdocker76/demotrain:v1', - command = ['python3', 'train.py'], - arguments=[ - '--trial', trial, - '--epoch', epoch, - '--patience', patience - ], - pvolumes={ - '/data': vop.volume - } - ) - -def GetMsg(comp1): - return dsl.ContainerOp( - name = 'Evaluate', - image = 'hubdocker76/demoeval:v2', - pvolumes={ - '/data': comp1.pvolumes['/data'] - }, - command = ['python3', 'eval.py'] - ) - -@dsl.pipeline( - name = 'face pipeline', - description = 'pipeline to detect facial landmarks') -def passing_parameter(trial, epoch, patience): - comp1 = SendMsg(trial, epoch, patience) - comp2 = GetMsg(comp1) - -if __name__ == '__main__': - import kfp.compiler as compiler - compiler.Compiler().compile(passing_parameter, __file__ + '.yaml') +import kfp +from kfp import dsl + +def SendMsg(trial, epoch, patience): + vop = dsl.VolumeOp(name="pvc", + resource_name="pvc", size='1Gi', + modes=dsl.VOLUME_MODE_RWO) + + return dsl.ContainerOp( + name = 'Train', + image = 'hubdocker76/demotrain:v1', + command = ['python3', 'train.py'], + arguments=[ + '--trial', trial, + '--epoch', epoch, + '--patience', patience + ], + pvolumes={ + '/data': vop.volume + } + ) + +def GetMsg(comp1): + return dsl.ContainerOp( + name = 'Evaluate', + image = 'hubdocker76/demoeval:v2', + pvolumes={ + '/data': comp1.pvolumes['/data'] + }, + command = ['python3', 'eval.py'] + ) + +@dsl.pipeline( + name = 'face pipeline', + description = 'pipeline to detect facial landmarks') +def passing_parameter(trial, epoch, patience): + comp1 = SendMsg(trial, epoch, patience) + comp2 = GetMsg(comp1) + +if __name__ == '__main__': + import kfp.compiler as compiler + compiler.Compiler().compile(passing_parameter, __file__ + '.yaml') diff --git a/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-kale.ipynb b/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-kale.ipynb index ed074e811..cfb4a1cc7 100644 --- a/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-kale.ipynb +++ b/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-kale.ipynb @@ -1,1024 +1,1024 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "# 🪙 G-Research Crypto Kale Pipeline\n", - "![](./images/vector-blockchain-poster.jpg)\n", - "\n", - "---\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "In this [Kaggle competition](https://www.kaggle.com/competitions/g-research-crypto-forecasting/overview), you'll use your machine learning expertise to forecast short term returns in 14 popular cryptocurrencies. The dataset provided contains information on historic trades for several cryptoassets, such as Bitcoin and Ethereum. \n", - "\n", - "> G-Research is a leading quantitative research and technology company. By using the latest scientific techniques, they produce world-beating predictive research and build advanced technology to analyse the world's data." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Install necessary packages\n", - "\n", - "We can install the necessary package by either running pip install --user or include everything in a requirements.txt file and run pip install --user -r requirements.txt. We have put the dependencies in a requirements.txt file so we will use the former method.\n", - "\n", - "NOTE: Do not forget to use the --user argument. It is necessary if you want to use Kale to transform this notebook into a Kubeflow pipeline. After installing python packages, restart notebook kernel before proceeding." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "!pip install -r requirements.txt --user --quiet" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Imports\n", - "\n", - "In this section we import the packages we need for this example. Make it a habit to gather your imports in a single place. It will make your life easier if you are going to transform this notebook into a Kubeflow pipeline using Kale." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "tags": [ - "imports" - ] - }, - "outputs": [], - "source": [ - "import os, random, subprocess\n", - "import pandas as pd\n", - "import numpy as np\n", - "import time, datetime, zipfile\n", - "import joblib, talib\n", - "from tqdm import tqdm\n", - "import lightgbm as lgb\n", - "\n", - "import warnings\n", - "warnings.filterwarnings(\"ignore\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Project hyper-parameters\n", - "\n", - "In this cell, we define the different hyper-parameters. Defining them in one place makes it easier to experiment with their values and also facilitates the execution of HP Tuning experiments using Kale and Katib." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "tags": [ - "pipeline-parameters" - ] - }, - "outputs": [], - "source": [ - "# Hyper-parameters\n", - "LR = 0.01\n", - "N_EST = 1200" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "Set random seed for reproducibility" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "def fix_all_seeds(seed):\n", - " np.random.seed(seed)\n", - " random.seed(seed)\n", - " os.environ['PYTHONHASHSEED'] = str(seed)\n", - "\n", - "fix_all_seeds(2022)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Download data\n", - "\n", - "In this section, we download the data from kaggle using the Kaggle API credentials" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "tags": [ - "block:download_data" - ] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "CompletedProcess(args=['kaggle', 'competitions', 'download', '-c', 'g-research-crypto-forecasting'], returncode=0)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# setup kaggle environment for data download\n", - "dataset = \"g-research-crypto-forecasting\"\n", - "\n", - "# setup kaggle environment for data download\n", - "with open('/secret/kaggle-secret/password', 'r') as file:\n", - " kaggle_key = file.read().rstrip()\n", - "with open('/secret/kaggle-secret/username', 'r') as file:\n", - " kaggle_user = file.read().rstrip()\n", - "\n", - "os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", - "\n", - "# download kaggle's g-research-crypto-forecast data\n", - "subprocess.run([\"kaggle\",\"competitions\", \"download\", \"-c\", dataset])" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "tags": [ - "block:" - ] - }, - "outputs": [], - "source": [ - "# path to download to\n", - "data_path = 'data'\n", - "\n", - "# extract g-research-crypto-forecasting.zip to load_data_path\n", - "with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", - " zip_ref.extractall(data_path, members=['train.csv', 'asset_details.csv'])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Load the dataset\n", - "\n", - "First, let us load and analyze the data.\n", - "\n", - "The data is in csv format, thus, we use the handy read_csv pandas method." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "tags": [ - "block:load_data", - "prev:download_data" - ] - }, - "outputs": [], - "source": [ - "TRAIN_CSV = f'{data_path}/train.csv'\n", - "ASSET_DETAILS_CSV = f'{data_path}/asset_details.csv'" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "df_train = pd.read_csv(TRAIN_CSV)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(24236806, 10)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Asset_IDWeightAsset_Name
104.304065Binance Coin
216.779922Bitcoin
022.397895Bitcoin Cash
1034.406719Cardano
1343.555348Dogecoin
351.386294EOS.IO
565.894403Ethereum
472.079442Ethereum Classic
1181.098612IOTA
692.397895Litecoin
12101.098612Maker
7111.609438Monero
9122.079442Stellar
8131.791759TRON
\n", - "
" - ], - "text/plain": [ - " Asset_ID Weight Asset_Name\n", - "1 0 4.304065 Binance Coin\n", - "2 1 6.779922 Bitcoin\n", - "0 2 2.397895 Bitcoin Cash\n", - "10 3 4.406719 Cardano\n", - "13 4 3.555348 Dogecoin\n", - "3 5 1.386294 EOS.IO\n", - "5 6 5.894403 Ethereum\n", - "4 7 2.079442 Ethereum Classic\n", - "11 8 1.098612 IOTA\n", - "6 9 2.397895 Litecoin\n", - "12 10 1.098612 Maker\n", - "7 11 1.609438 Monero\n", - "9 12 2.079442 Stellar\n", - "8 13 1.791759 TRON" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_asset_details = pd.read_csv(ASSET_DETAILS_CSV).sort_values(\"Asset_ID\")\n", - "df_asset_details" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "df_train['datetime'] = pd.to_datetime(df_train['timestamp'], unit='s')\n", - "df_train = df_train[df_train['datetime'] >= '2020-01-01 00:00:00'].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(12228898, 11)" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "Timestamp('2021-09-21 00:00:00')" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train['datetime'].max()" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "timestamp 0\n", - "Asset_ID 0\n", - "Count 0\n", - "Open 0\n", - "High 0\n", - "Low 0\n", - "Close 0\n", - "Volume 0\n", - "VWAP 9\n", - "Target 262453\n", - "datetime 0\n", - "dtype: int64" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train.isna().sum()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "### Define Pipeline Functions" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "tags": [ - "functions" - ] - }, - "outputs": [], - "source": [ - "# define the evaluation metric\n", - "def weighted_correlation(a, train_data):\n", - " \n", - " weights = train_data.add_w.values.flatten()\n", - " b = train_data.get_label()\n", - " \n", - " \n", - " w = np.ravel(weights)\n", - " a = np.ravel(a)\n", - " b = np.ravel(b)\n", - "\n", - " sum_w = np.sum(w)\n", - " mean_a = np.sum(a * w) / sum_w\n", - " mean_b = np.sum(b * w) / sum_w\n", - " var_a = np.sum(w * np.square(a - mean_a)) / sum_w\n", - " var_b = np.sum(w * np.square(b - mean_b)) / sum_w\n", - "\n", - " cov = np.sum((a * b * w)) / np.sum(w) - mean_a * mean_b\n", - " corr = cov / np.sqrt(var_a * var_b)\n", - "\n", - " return 'eval_wcorr', corr, True" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "tags": [ - "functions" - ] - }, - "outputs": [], - "source": [ - "def RSI(df, n):\n", - " return talib.RSI(df['Close'], n)\n", - "\n", - "def ATR(df, n):\n", - " return talib.ATR(df[\"High\"], df.Low, df.Close, n)\n", - "\n", - "#Create a function to calculate the Double Exponential Moving Average (DEMA)\n", - "def DEMA(data, time_period):\n", - " #Calculate the Exponential Moving Average for some time_period (in days)\n", - " EMA = data['Close'].ewm(span=time_period, adjust=False).mean()\n", - " #Calculate the DEMA\n", - " DEMA = 2*EMA - EMA.ewm(span=time_period, adjust=False).mean()\n", - " return DEMA\n", - "\n", - "def upper_shadow(df):\n", - " return df['High'] - np.maximum(df['Close'], df['Open'])\n", - "\n", - "def lower_shadow(df):\n", - " return np.minimum(df['Close'], df['Open']) - df['Low']" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Feature Engineering" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "tags": [ - "block:feature_engineering", - "prev:load_data" - ] - }, - "outputs": [], - "source": [ - "def get_features(df, \n", - " asset_id, \n", - " train=True):\n", - " '''\n", - " This function takes a dataframe with all asset data and return the lagged features for a single asset.\n", - " \n", - " df - Full dataframe with all assets included\n", - " asset_id - integer from 0-13 inclusive to represent a cryptocurrency asset\n", - " train - True - you are training your model\n", - " - False - you are submitting your model via api\n", - " '''\n", - " # filter based on asset id\n", - " df = df[df['Asset_ID']==asset_id]\n", - " \n", - " # sort based on time stamp\n", - " df = df.sort_values('timestamp')\n", - " \n", - " if train == True:\n", - " df_feat = df.copy()\n", - " \n", - " # define a train_flg column to split your data into train and validation\n", - " totimestamp = lambda s: np.int32(time.mktime(datetime.datetime.strptime(s, \"%d/%m/%Y\").timetuple()))\n", - " valid_window = [totimestamp(\"01/05/2021\")]\n", - " \n", - " df_feat['train_flg'] = np.where(df_feat['timestamp']>=valid_window[0], 0,1)\n", - " df_feat = df_feat[['timestamp','Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','Target','train_flg']].copy()\n", - " else:\n", - " df = df.sort_values('row_id')\n", - " df_feat = df[['Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','row_id']].copy()\n", - " \n", - " for i in tqdm([30, 120, 240]):\n", - " # creating technical indicators\n", - " df_feat[f'RSI_{i}'] = RSI(df_feat, i)\n", - " df_feat[f'ATR_{i}'] = ATR(df_feat, i)\n", - " df_feat[f'DEMA_{i}'] = DEMA(df_feat, i)\n", - "\n", - " for i in tqdm([30, 120, 240]):\n", - " # creating lag features\n", - " df_feat[f'sma_{i}'] = df_feat['Close'].rolling(i).mean()/df_feat['Close'] -1\n", - " df_feat[f'return_{i}'] = df_feat['Close']/df_feat['Close'].shift(i) -1\n", - " \n", - " # new featu# creating technical indicators featureses\n", - " df_feat['HL'] = np.log(df_feat['High'] - df_feat['Low'])\n", - " df_feat['OC'] = np.log(df_feat['Close'] - df_feat['Open'])\n", - " \n", - " df_feat['lower_shadow'] = np.log(lower_shadow(df)) \n", - " df_feat['upper_shadow'] = np.log(upper_shadow(df))\n", - " \n", - " # replace inf with nan\n", - " df_feat.replace([np.inf, -np.inf], np.nan, inplace=True)\n", - " \n", - " # datetime features\n", - " df_feat['Date'] = pd.to_datetime(df_feat['timestamp'], unit='s')\n", - " df_feat['Day'] = df_feat['Date'].dt.weekday.astype(np.int32)\n", - " df_feat[\"dayofyear\"] = df_feat['Date'].dt.dayofyear\n", - " df_feat[\"weekofyear\"] = df_feat['Date'].dt.weekofyear\n", - " df_feat[\"season\"] = ((df_feat['Date'].dt.month)%12 + 3)//3\n", - " \n", - "\n", - " df_feat = df_feat.drop(['Open','Close','High','Low', 'Volume', 'Date'], axis=1)\n", - " \n", - " # fill nan values with 0\n", - " df_feat = df_feat.fillna(0)\n", - " \n", - " return df_feat" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 3/3 [00:00<00:00, 7.64it/s]\n", - "100%|██████████| 3/3 [00:00<00:00, 12.66it/s]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 3/3 [00:00<00:00, 7.61it/s]\n", - "100%|██████████| 3/3 [00:00<00:00, 16.32it/s]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 3/3 [00:00<00:00, 9.89it/s]\n", - "100%|██████████| 3/3 [00:00<00:00, 22.05it/s]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 3/3 [00:00<00:00, 8.52it/s]\n", - "100%|██████████| 3/3 [00:00<00:00, 17.92it/s]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 3/3 [00:00<00:00, 10.35it/s]\n", - "100%|██████████| 3/3 [00:00<00:00, 22.56it/s]\n" - ] - } - ], - "source": [ - "# create your feature dataframe for each asset and concatenate\n", - "feature_df = pd.DataFrame()\n", - "for i in range(14):\n", - " print(i)\n", - " feature_df = pd.concat([feature_df,get_features(df_train,i,train=True)])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Merge Assets Features" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "block:merge_assets_features", - "prev:load_data", - "prev:feature_engineering" - ] - }, - "outputs": [], - "source": [ - "# assign weight column feature dataframe\n", - "feature_df = pd.merge(feature_df, df_asset_details[['Asset_ID','Weight']], how='left', on=['Asset_ID'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "feature_df.columns" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Modelling" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "block:modelling", - "prev:merge_assets_features" - ] - }, - "outputs": [], - "source": [ - "# define features for LGBM\n", - "features = ['Asset_ID', 'RSI_30', 'ATR_30',\n", - " 'DEMA_30', 'RSI_120', 'ATR_120', 'DEMA_120', 'RSI_240', 'ATR_240',\n", - " 'DEMA_240', 'sma_30', 'return_30', 'sma_120', 'return_120', 'sma_240',\n", - " 'return_240', 'HL', 'OC', 'lower_shadow', 'upper_shadow', 'Day',\n", - " 'dayofyear', 'weekofyear', 'season']\n", - "categoricals = ['Asset_ID']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# define train and validation weights and datasets\n", - "weights_train = feature_df.query('train_flg == 1')[['Weight']]\n", - "weights_test = feature_df.query('train_flg == 0')[['Weight']]\n", - "\n", - "train_dataset = lgb.Dataset(feature_df.query('train_flg == 1')[features], \n", - " feature_df.query('train_flg == 1')['Target'].values, \n", - " feature_name = features,\n", - " categorical_feature= categoricals)\n", - "val_dataset = lgb.Dataset(feature_df.query('train_flg == 0')[features], \n", - " feature_df.query('train_flg == 0')['Target'].values, \n", - " feature_name = features,\n", - " categorical_feature= categoricals)\n", - "\n", - "train_dataset.add_w = weights_train\n", - "val_dataset.add_w = weights_test\n", - "\n", - "evals_result = {}\n", - "params = {'n_estimators': int(N_EST),\n", - " 'objective': 'regression',\n", - " 'metric': 'rmse',\n", - " 'boosting_type': 'gbdt',\n", - " 'max_depth': -1, \n", - " 'learning_rate': float(LR),\n", - " 'seed': 2022,\n", - " 'verbose': -1,\n", - " }\n", - "\n", - "# train LGBM2\n", - "model = lgb.train(params = params,\n", - " train_set = train_dataset, \n", - " valid_sets = [val_dataset],\n", - " early_stopping_rounds=60,\n", - " verbose_eval = 30,\n", - " feval=weighted_correlation,\n", - " evals_result = evals_result \n", - " )\n", - "\n", - "joblib.dump(model, 'lgb.jl')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "fea_imp = pd.DataFrame({'imp':model.feature_importance(), 'col': features})\n", - "fea_imp = fea_imp.sort_values(['imp', 'col'], ascending=[True, False]).iloc[-30:]\n", - "_ = fea_imp.plot(kind='barh', x='col', y='imp', figsize=(20, 10))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Evaluation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "block:evaluation_result", - "prev:modelling" - ] - }, - "outputs": [], - "source": [ - "model = joblib.load('lgb.jl')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "root_mean_squared_error = model.best_score.get('valid_0').get('rmse')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "weighted_correlation = model.best_score.get('valid_0').get('eval_wcorr')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Pipeline Metrics" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "pipeline-metrics" - ] - }, - "outputs": [], - "source": [ - "print(root_mean_squared_error)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "pipeline-metrics" - ] - }, - "outputs": [], - "source": [ - "print(weighted_correlation)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kubeflow_notebook": { - "autosnapshot": true, - "experiment": { - "id": "2efb8e27-3b2e-439b-a53c-b1f9d7b94cfc", - "name": "g-research-crypto-forecasting" - }, - "experiment_name": "g-research-crypto-forecasting", - "katib_metadata": { - "algorithm": { - "algorithmName": "grid" - }, - "maxFailedTrialCount": 3, - "maxTrialCount": 12, - "objective": { - "objectiveMetricName": "", - "type": "minimize" - }, - "parallelTrialCount": 3, - "parameters": [] - }, - "katib_run": false, - "pipeline_description": "forecasting short term returns in 14 popular cryptocurrencies.", - "pipeline_name": "g-research-crypto-forecasting-pipeline", - "snapshot_volumes": true, - "steps_defaults": [ - "label:access-ml-pipeline:true", - "label:kaggle-secret:true", - "label:access-rok:true" - ], - "volume_access_mode": "rwm", - "volumes": [ - { - "annotations": [], - "mount_point": "/home/jovyan", - "name": "demo-workspace-fb99v", - "size": 15, - "size_type": "Gi", - "snapshot": false, - "type": "clone" - } - ] - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.9" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# 🪙 G-Research Crypto Kale Pipeline\n", + "![](./images/vector-blockchain-poster.jpg)\n", + "\n", + "---\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "In this [Kaggle competition](https://www.kaggle.com/competitions/g-research-crypto-forecasting/overview), you'll use your machine learning expertise to forecast short term returns in 14 popular cryptocurrencies. The dataset provided contains information on historic trades for several cryptoassets, such as Bitcoin and Ethereum. \n", + "\n", + "> G-Research is a leading quantitative research and technology company. By using the latest scientific techniques, they produce world-beating predictive research and build advanced technology to analyse the world's data." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Install necessary packages\n", + "\n", + "We can install the necessary package by either running pip install --user or include everything in a requirements.txt file and run pip install --user -r requirements.txt. We have put the dependencies in a requirements.txt file so we will use the former method.\n", + "\n", + "NOTE: Do not forget to use the --user argument. It is necessary if you want to use Kale to transform this notebook into a Kubeflow pipeline. After installing python packages, restart notebook kernel before proceeding." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "!pip install -r requirements.txt --user --quiet" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Imports\n", + "\n", + "In this section we import the packages we need for this example. Make it a habit to gather your imports in a single place. It will make your life easier if you are going to transform this notebook into a Kubeflow pipeline using Kale." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [ + "imports" + ] + }, + "outputs": [], + "source": [ + "import os, random, subprocess\n", + "import pandas as pd\n", + "import numpy as np\n", + "import time, datetime, zipfile\n", + "import joblib, talib\n", + "from tqdm import tqdm\n", + "import lightgbm as lgb\n", + "\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Project hyper-parameters\n", + "\n", + "In this cell, we define the different hyper-parameters. Defining them in one place makes it easier to experiment with their values and also facilitates the execution of HP Tuning experiments using Kale and Katib." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "pipeline-parameters" + ] + }, + "outputs": [], + "source": [ + "# Hyper-parameters\n", + "LR = 0.01\n", + "N_EST = 1200" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "Set random seed for reproducibility" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "def fix_all_seeds(seed):\n", + " np.random.seed(seed)\n", + " random.seed(seed)\n", + " os.environ['PYTHONHASHSEED'] = str(seed)\n", + "\n", + "fix_all_seeds(2022)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Download data\n", + "\n", + "In this section, we download the data from kaggle using the Kaggle API credentials" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [ + "block:download_data" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "CompletedProcess(args=['kaggle', 'competitions', 'download', '-c', 'g-research-crypto-forecasting'], returncode=0)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# setup kaggle environment for data download\n", + "dataset = \"g-research-crypto-forecasting\"\n", + "\n", + "# setup kaggle environment for data download\n", + "with open('/secret/kaggle-secret/password', 'r') as file:\n", + " kaggle_key = file.read().rstrip()\n", + "with open('/secret/kaggle-secret/username', 'r') as file:\n", + " kaggle_user = file.read().rstrip()\n", + "\n", + "os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", + "\n", + "# download kaggle's g-research-crypto-forecast data\n", + "subprocess.run([\"kaggle\",\"competitions\", \"download\", \"-c\", dataset])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [ + "block:" + ] + }, + "outputs": [], + "source": [ + "# path to download to\n", + "data_path = 'data'\n", + "\n", + "# extract g-research-crypto-forecasting.zip to load_data_path\n", + "with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", + " zip_ref.extractall(data_path, members=['train.csv', 'asset_details.csv'])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Load the dataset\n", + "\n", + "First, let us load and analyze the data.\n", + "\n", + "The data is in csv format, thus, we use the handy read_csv pandas method." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "block:load_data", + "prev:download_data" + ] + }, + "outputs": [], + "source": [ + "TRAIN_CSV = f'{data_path}/train.csv'\n", + "ASSET_DETAILS_CSV = f'{data_path}/asset_details.csv'" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df_train = pd.read_csv(TRAIN_CSV)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(24236806, 10)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Asset_IDWeightAsset_Name
104.304065Binance Coin
216.779922Bitcoin
022.397895Bitcoin Cash
1034.406719Cardano
1343.555348Dogecoin
351.386294EOS.IO
565.894403Ethereum
472.079442Ethereum Classic
1181.098612IOTA
692.397895Litecoin
12101.098612Maker
7111.609438Monero
9122.079442Stellar
8131.791759TRON
\n", + "
" + ], + "text/plain": [ + " Asset_ID Weight Asset_Name\n", + "1 0 4.304065 Binance Coin\n", + "2 1 6.779922 Bitcoin\n", + "0 2 2.397895 Bitcoin Cash\n", + "10 3 4.406719 Cardano\n", + "13 4 3.555348 Dogecoin\n", + "3 5 1.386294 EOS.IO\n", + "5 6 5.894403 Ethereum\n", + "4 7 2.079442 Ethereum Classic\n", + "11 8 1.098612 IOTA\n", + "6 9 2.397895 Litecoin\n", + "12 10 1.098612 Maker\n", + "7 11 1.609438 Monero\n", + "9 12 2.079442 Stellar\n", + "8 13 1.791759 TRON" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_asset_details = pd.read_csv(ASSET_DETAILS_CSV).sort_values(\"Asset_ID\")\n", + "df_asset_details" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df_train['datetime'] = pd.to_datetime(df_train['timestamp'], unit='s')\n", + "df_train = df_train[df_train['datetime'] >= '2020-01-01 00:00:00'].copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(12228898, 11)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Timestamp('2021-09-21 00:00:00')" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train['datetime'].max()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "timestamp 0\n", + "Asset_ID 0\n", + "Count 0\n", + "Open 0\n", + "High 0\n", + "Low 0\n", + "Close 0\n", + "Volume 0\n", + "VWAP 9\n", + "Target 262453\n", + "datetime 0\n", + "dtype: int64" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train.isna().sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "### Define Pipeline Functions" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "tags": [ + "functions" + ] + }, + "outputs": [], + "source": [ + "# define the evaluation metric\n", + "def weighted_correlation(a, train_data):\n", + " \n", + " weights = train_data.add_w.values.flatten()\n", + " b = train_data.get_label()\n", + " \n", + " \n", + " w = np.ravel(weights)\n", + " a = np.ravel(a)\n", + " b = np.ravel(b)\n", + "\n", + " sum_w = np.sum(w)\n", + " mean_a = np.sum(a * w) / sum_w\n", + " mean_b = np.sum(b * w) / sum_w\n", + " var_a = np.sum(w * np.square(a - mean_a)) / sum_w\n", + " var_b = np.sum(w * np.square(b - mean_b)) / sum_w\n", + "\n", + " cov = np.sum((a * b * w)) / np.sum(w) - mean_a * mean_b\n", + " corr = cov / np.sqrt(var_a * var_b)\n", + "\n", + " return 'eval_wcorr', corr, True" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "tags": [ + "functions" + ] + }, + "outputs": [], + "source": [ + "def RSI(df, n):\n", + " return talib.RSI(df['Close'], n)\n", + "\n", + "def ATR(df, n):\n", + " return talib.ATR(df[\"High\"], df.Low, df.Close, n)\n", + "\n", + "#Create a function to calculate the Double Exponential Moving Average (DEMA)\n", + "def DEMA(data, time_period):\n", + " #Calculate the Exponential Moving Average for some time_period (in days)\n", + " EMA = data['Close'].ewm(span=time_period, adjust=False).mean()\n", + " #Calculate the DEMA\n", + " DEMA = 2*EMA - EMA.ewm(span=time_period, adjust=False).mean()\n", + " return DEMA\n", + "\n", + "def upper_shadow(df):\n", + " return df['High'] - np.maximum(df['Close'], df['Open'])\n", + "\n", + "def lower_shadow(df):\n", + " return np.minimum(df['Close'], df['Open']) - df['Low']" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Feature Engineering" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "tags": [ + "block:feature_engineering", + "prev:load_data" + ] + }, + "outputs": [], + "source": [ + "def get_features(df, \n", + " asset_id, \n", + " train=True):\n", + " '''\n", + " This function takes a dataframe with all asset data and return the lagged features for a single asset.\n", + " \n", + " df - Full dataframe with all assets included\n", + " asset_id - integer from 0-13 inclusive to represent a cryptocurrency asset\n", + " train - True - you are training your model\n", + " - False - you are submitting your model via api\n", + " '''\n", + " # filter based on asset id\n", + " df = df[df['Asset_ID']==asset_id]\n", + " \n", + " # sort based on time stamp\n", + " df = df.sort_values('timestamp')\n", + " \n", + " if train == True:\n", + " df_feat = df.copy()\n", + " \n", + " # define a train_flg column to split your data into train and validation\n", + " totimestamp = lambda s: np.int32(time.mktime(datetime.datetime.strptime(s, \"%d/%m/%Y\").timetuple()))\n", + " valid_window = [totimestamp(\"01/05/2021\")]\n", + " \n", + " df_feat['train_flg'] = np.where(df_feat['timestamp']>=valid_window[0], 0,1)\n", + " df_feat = df_feat[['timestamp','Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','Target','train_flg']].copy()\n", + " else:\n", + " df = df.sort_values('row_id')\n", + " df_feat = df[['Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','row_id']].copy()\n", + " \n", + " for i in tqdm([30, 120, 240]):\n", + " # creating technical indicators\n", + " df_feat[f'RSI_{i}'] = RSI(df_feat, i)\n", + " df_feat[f'ATR_{i}'] = ATR(df_feat, i)\n", + " df_feat[f'DEMA_{i}'] = DEMA(df_feat, i)\n", + "\n", + " for i in tqdm([30, 120, 240]):\n", + " # creating lag features\n", + " df_feat[f'sma_{i}'] = df_feat['Close'].rolling(i).mean()/df_feat['Close'] -1\n", + " df_feat[f'return_{i}'] = df_feat['Close']/df_feat['Close'].shift(i) -1\n", + " \n", + " # new featu# creating technical indicators featureses\n", + " df_feat['HL'] = np.log(df_feat['High'] - df_feat['Low'])\n", + " df_feat['OC'] = np.log(df_feat['Close'] - df_feat['Open'])\n", + " \n", + " df_feat['lower_shadow'] = np.log(lower_shadow(df)) \n", + " df_feat['upper_shadow'] = np.log(upper_shadow(df))\n", + " \n", + " # replace inf with nan\n", + " df_feat.replace([np.inf, -np.inf], np.nan, inplace=True)\n", + " \n", + " # datetime features\n", + " df_feat['Date'] = pd.to_datetime(df_feat['timestamp'], unit='s')\n", + " df_feat['Day'] = df_feat['Date'].dt.weekday.astype(np.int32)\n", + " df_feat[\"dayofyear\"] = df_feat['Date'].dt.dayofyear\n", + " df_feat[\"weekofyear\"] = df_feat['Date'].dt.weekofyear\n", + " df_feat[\"season\"] = ((df_feat['Date'].dt.month)%12 + 3)//3\n", + " \n", + "\n", + " df_feat = df_feat.drop(['Open','Close','High','Low', 'Volume', 'Date'], axis=1)\n", + " \n", + " # fill nan values with 0\n", + " df_feat = df_feat.fillna(0)\n", + " \n", + " return df_feat" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 3/3 [00:00<00:00, 7.64it/s]\n", + "100%|██████████| 3/3 [00:00<00:00, 12.66it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 3/3 [00:00<00:00, 7.61it/s]\n", + "100%|██████████| 3/3 [00:00<00:00, 16.32it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 3/3 [00:00<00:00, 9.89it/s]\n", + "100%|██████████| 3/3 [00:00<00:00, 22.05it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 3/3 [00:00<00:00, 8.52it/s]\n", + "100%|██████████| 3/3 [00:00<00:00, 17.92it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 3/3 [00:00<00:00, 10.35it/s]\n", + "100%|██████████| 3/3 [00:00<00:00, 22.56it/s]\n" + ] + } + ], + "source": [ + "# create your feature dataframe for each asset and concatenate\n", + "feature_df = pd.DataFrame()\n", + "for i in range(14):\n", + " print(i)\n", + " feature_df = pd.concat([feature_df,get_features(df_train,i,train=True)])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Merge Assets Features" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "block:merge_assets_features", + "prev:load_data", + "prev:feature_engineering" + ] + }, + "outputs": [], + "source": [ + "# assign weight column feature dataframe\n", + "feature_df = pd.merge(feature_df, df_asset_details[['Asset_ID','Weight']], how='left', on=['Asset_ID'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "feature_df.columns" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Modelling" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "block:modelling", + "prev:merge_assets_features" + ] + }, + "outputs": [], + "source": [ + "# define features for LGBM\n", + "features = ['Asset_ID', 'RSI_30', 'ATR_30',\n", + " 'DEMA_30', 'RSI_120', 'ATR_120', 'DEMA_120', 'RSI_240', 'ATR_240',\n", + " 'DEMA_240', 'sma_30', 'return_30', 'sma_120', 'return_120', 'sma_240',\n", + " 'return_240', 'HL', 'OC', 'lower_shadow', 'upper_shadow', 'Day',\n", + " 'dayofyear', 'weekofyear', 'season']\n", + "categoricals = ['Asset_ID']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# define train and validation weights and datasets\n", + "weights_train = feature_df.query('train_flg == 1')[['Weight']]\n", + "weights_test = feature_df.query('train_flg == 0')[['Weight']]\n", + "\n", + "train_dataset = lgb.Dataset(feature_df.query('train_flg == 1')[features], \n", + " feature_df.query('train_flg == 1')['Target'].values, \n", + " feature_name = features,\n", + " categorical_feature= categoricals)\n", + "val_dataset = lgb.Dataset(feature_df.query('train_flg == 0')[features], \n", + " feature_df.query('train_flg == 0')['Target'].values, \n", + " feature_name = features,\n", + " categorical_feature= categoricals)\n", + "\n", + "train_dataset.add_w = weights_train\n", + "val_dataset.add_w = weights_test\n", + "\n", + "evals_result = {}\n", + "params = {'n_estimators': int(N_EST),\n", + " 'objective': 'regression',\n", + " 'metric': 'rmse',\n", + " 'boosting_type': 'gbdt',\n", + " 'max_depth': -1, \n", + " 'learning_rate': float(LR),\n", + " 'seed': 2022,\n", + " 'verbose': -1,\n", + " }\n", + "\n", + "# train LGBM2\n", + "model = lgb.train(params = params,\n", + " train_set = train_dataset, \n", + " valid_sets = [val_dataset],\n", + " early_stopping_rounds=60,\n", + " verbose_eval = 30,\n", + " feval=weighted_correlation,\n", + " evals_result = evals_result \n", + " )\n", + "\n", + "joblib.dump(model, 'lgb.jl')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "fea_imp = pd.DataFrame({'imp':model.feature_importance(), 'col': features})\n", + "fea_imp = fea_imp.sort_values(['imp', 'col'], ascending=[True, False]).iloc[-30:]\n", + "_ = fea_imp.plot(kind='barh', x='col', y='imp', figsize=(20, 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Evaluation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "block:evaluation_result", + "prev:modelling" + ] + }, + "outputs": [], + "source": [ + "model = joblib.load('lgb.jl')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "root_mean_squared_error = model.best_score.get('valid_0').get('rmse')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "weighted_correlation = model.best_score.get('valid_0').get('eval_wcorr')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Pipeline Metrics" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "pipeline-metrics" + ] + }, + "outputs": [], + "source": [ + "print(root_mean_squared_error)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "pipeline-metrics" + ] + }, + "outputs": [], + "source": [ + "print(weighted_correlation)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "kubeflow_notebook": { + "autosnapshot": true, + "experiment": { + "id": "2efb8e27-3b2e-439b-a53c-b1f9d7b94cfc", + "name": "g-research-crypto-forecasting" + }, + "experiment_name": "g-research-crypto-forecasting", + "katib_metadata": { + "algorithm": { + "algorithmName": "grid" + }, + "maxFailedTrialCount": 3, + "maxTrialCount": 12, + "objective": { + "objectiveMetricName": "", + "type": "minimize" + }, + "parallelTrialCount": 3, + "parameters": [] + }, + "katib_run": false, + "pipeline_description": "forecasting short term returns in 14 popular cryptocurrencies.", + "pipeline_name": "g-research-crypto-forecasting-pipeline", + "snapshot_volumes": true, + "steps_defaults": [ + "label:access-ml-pipeline:true", + "label:kaggle-secret:true", + "label:access-rok:true" + ], + "volume_access_mode": "rwm", + "volumes": [ + { + "annotations": [], + "mount_point": "/home/jovyan", + "name": "demo-workspace-fb99v", + "size": 15, + "size_type": "Gi", + "snapshot": false, + "type": "clone" + } + ] + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-kfp.ipynb b/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-kfp.ipynb index 393f2d12f..ba4ca7493 100644 --- a/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-kfp.ipynb +++ b/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-kfp.ipynb @@ -1,810 +1,810 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "# 🪙 G-Research Crypto Kubeflow Pipeline\n", - "![](./images/vector-blockchain-poster.jpg)\n", - "\n", - "---\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "In this [Kaggle competition](https://www.kaggle.com/competitions/g-research-crypto-forecasting/overview), you'll use your machine learning expertise to forecast short term returns in 14 popular cryptocurrencies. The dataset provided contains information on historic trades for several cryptoassets, such as Bitcoin and Ethereum. \n", - "\n", - "> G-Research is a leading quantitative research and technology company. By using the latest scientific techniques, they produce world-beating predictive research and build advanced technology to analyse the world's data." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Install relevant libraries\n", - "\n", - "\n", - ">Update pip `pip install --user --upgrade pip`\n", - "\n", - ">Install and upgrade kubeflow sdk `pip install kfp --upgrade --user --quiet`\n", - "\n", - "You may need to restart your notebook kernel after installing the kfp sdk" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: pip in /usr/local/lib/python3.6/dist-packages (21.3.1)\n" - ] - } - ], - "source": [ - "!pip install --user --upgrade pip" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "!pip install kfp --upgrade --user --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Name: kfp\n", - "Version: 1.8.11\n", - "Summary: KubeFlow Pipelines SDK\n", - "Home-page: https://github.com/kubeflow/pipelines\n", - "Author: The Kubeflow Authors\n", - "Author-email: \n", - "License: UNKNOWN\n", - "Location: /home/jovyan/.local/lib/python3.6/site-packages\n", - "Requires: absl-py, click, cloudpickle, dataclasses, Deprecated, docstring-parser, fire, google-api-python-client, google-auth, google-cloud-storage, jsonschema, kfp-pipeline-spec, kfp-server-api, kubernetes, protobuf, pydantic, PyYAML, requests-toolbelt, strip-hints, tabulate, typer, typing-extensions, uritemplate\n", - "Required-by: kubeflow-kale\n" - ] - } - ], - "source": [ - "# confirm the kfp sdk\n", - "! pip show kfp" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "tags": [ - "imports" - ] - }, - "outputs": [], - "source": [ - "import kfp\n", - "import kfp.components as comp\n", - "import kfp.dsl as dsl\n", - "from kfp.components import OutputPath\n", - "from typing import NamedTuple" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "# Kubeflow pipeline component creation\n", - "\n", - "## Download the dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# download data step\n", - "def download_data(dataset, \n", - " data_path):\n", - " \n", - " # install the necessary libraries\n", - " import os, sys, subprocess, zipfile, pickle;\n", - " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','kaggle'])\n", - " \n", - " # import libraries\n", - " import pandas as pd\n", - "\n", - " # setup kaggle environment for data download\n", - " with open('/secret/kaggle-secret/password', 'r') as file:\n", - " kaggle_key = file.read().rstrip()\n", - " with open('/secret/kaggle-secret/username', 'r') as file:\n", - " kaggle_user = file.read().rstrip()\n", - " \n", - " os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", - " \n", - " # create data_path directory\n", - " if not os.path.exists(data_path):\n", - " os.makedirs(data_path)\n", - " \n", - " # download kaggle's g-research-crypto-forecasting data\n", - " subprocess.run([\"kaggle\",\"competitions\", \"download\", \"-c\", dataset])\n", - " \n", - " # extract 'train.csv' and 'asset_details.csv' in g-research-crypto-forecasting.zip to data_path\n", - " with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", - " zip_ref.extractall(data_path, members=['train.csv', 'asset_details.csv'])\n", - " \n", - " return(print('Done!'))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Load Data" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "# load data step\n", - "def load_data(data_path):\n", - " \n", - " # install the necessary libraries\n", - " import os, sys, subprocess, pickle;\n", - " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", - " \n", - " # import libraries\n", - " import pandas as pd\n", - "\n", - " TRAIN_CSV = f'{data_path}/train.csv'\n", - " ASSET_DETAILS_CSV = f'{data_path}/asset_details.csv'\n", - " \n", - " # read TRAIN_CSV and ASSET_DETAILS_CSV\n", - " df_train = pd.read_csv(TRAIN_CSV)\n", - " df_asset_details = pd.read_csv(ASSET_DETAILS_CSV).sort_values(\"Asset_ID\")\n", - " \n", - " df_train['datetime'] = pd.to_datetime(df_train['timestamp'], unit='s')\n", - " df_train = df_train[df_train['datetime'] >= '2020-01-01 00:00:00'].copy()\n", - " \n", - " # Save the df_train data as a pickle file to be used by the feature_engineering component.\n", - " with open(f'{data_path}/df_train', 'wb') as f:\n", - " pickle.dump(df_train, f)\n", - " \n", - " # Save the df_train data as a pickle file to be used by the merge_data component.\n", - " with open(f'{data_path}/df_asset_details', 'wb') as g:\n", - " pickle.dump(df_asset_details, g)\n", - "\n", - " \n", - " return(print('Done!'))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Feature Engineering" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "# feature engineering step\n", - "\n", - "def feature_engineering(data_path):\n", - " \n", - " # install the necessary libraries\n", - " import sys, subprocess;\n", - " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','tqdm'])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','talib-binary'])\n", - " \n", - " # import Library\n", - " import os, pickle, time, talib, datetime;\n", - " import numpy as np\n", - " import pandas as pd\n", - " from tqdm import tqdm\n", - "\n", - " # loading the df_train data\n", - " with open(f'{data_path}/df_train', 'rb') as f:\n", - " df_train = pickle.load(f)\n", - " \n", - " # creating technical indicators\n", - " \n", - " # Create a function to calculate the Relative Strength Index\n", - " def RSI(df, n):\n", - " return talib.RSI(df['Close'], n)\n", - " \n", - " # Create a function to calculate the Average True Range\n", - " def ATR(df, n):\n", - " return talib.ATR(df[\"High\"], df.Low, df.Close, n)\n", - "\n", - " # Create a function to calculate the Double Exponential Moving Average (DEMA)\n", - " def DEMA(data, time_period):\n", - " #Calculate the Exponential Moving Average for some time_period (in days)\n", - " EMA = data['Close'].ewm(span=time_period, adjust=False).mean()\n", - " #Calculate the DEMA\n", - " DEMA = 2*EMA - EMA.ewm(span=time_period, adjust=False).mean()\n", - " return DEMA\n", - " \n", - " # Create a function to calculate the upper_shadow\n", - " def upper_shadow(df):\n", - " return df['High'] - np.maximum(df['Close'], df['Open'])\n", - " \n", - " # Create a function to calculate the lower_shadow\n", - " def lower_shadow(df):\n", - " return np.minimum(df['Close'], df['Open']) - df['Low']\n", - " \n", - " \n", - " def get_features(df, asset_id, train=True):\n", - " '''\n", - " This function takes a dataframe with all asset data and return the lagged features for a single asset.\n", - "\n", - " df - Full dataframe with all assets included\n", - " asset_id - integer from 0-13 inclusive to represent a cryptocurrency asset\n", - " train - True - you are training your model\n", - " - False - you are submitting your model via api\n", - " '''\n", - " # filter based on asset id\n", - " df = df[df['Asset_ID']==asset_id]\n", - "\n", - " # sort based on time stamp\n", - " df = df.sort_values('timestamp')\n", - "\n", - " if train == True:\n", - " df_feat = df.copy()\n", - "\n", - " # define a train_flg column to split your data into train and validation\n", - " totimestamp = lambda s: np.int32(time.mktime(datetime.datetime.strptime(s, \"%d/%m/%Y\").timetuple()))\n", - " valid_window = [totimestamp(\"01/05/2021\")]\n", - "\n", - " df_feat['train_flg'] = np.where(df_feat['timestamp']>=valid_window[0], 0,1)\n", - " df_feat = df_feat[['timestamp','Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','Target','train_flg']].copy()\n", - " else:\n", - " df = df.sort_values('row_id')\n", - " df_feat = df[['Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','row_id']].copy()\n", - "\n", - " for i in tqdm([30, 120, 240]):\n", - " # Applyin technical indicators\n", - " df_feat[f'RSI_{i}'] = RSI(df_feat, i)\n", - " df_feat[f'ATR_{i}'] = ATR(df_feat, i)\n", - " df_feat[f'DEMA_{i}'] = DEMA(df_feat, i)\n", - "\n", - " for i in tqdm([30, 120, 240]):\n", - " # creating lag features\n", - " df_feat[f'sma_{i}'] = df_feat['Close'].rolling(i).mean()/df_feat['Close'] -1\n", - " df_feat[f'return_{i}'] = df_feat['Close']/df_feat['Close'].shift(i) -1\n", - "\n", - " # new features\n", - " df_feat['HL'] = np.log(df_feat['High'] - df_feat['Low'])\n", - " df_feat['OC'] = np.log(df_feat['Close'] - df_feat['Open'])\n", - " \n", - " # Applyin lower_shadow and upper_shadow indicators\n", - " df_feat['lower_shadow'] = np.log(lower_shadow(df)) \n", - " df_feat['upper_shadow'] = np.log(upper_shadow(df))\n", - "\n", - " # replace inf with nan\n", - " df_feat.replace([np.inf, -np.inf], np.nan, inplace=True)\n", - "\n", - " # datetime features\n", - " df_feat['Date'] = pd.to_datetime(df_feat['timestamp'], unit='s')\n", - " df_feat['Day'] = df_feat['Date'].dt.weekday.astype(np.int32)\n", - " df_feat[\"dayofyear\"] = df_feat['Date'].dt.dayofyear\n", - " df_feat[\"weekofyear\"] = df_feat['Date'].dt.weekofyear\n", - " df_feat[\"season\"] = ((df_feat['Date'].dt.month)%12 + 3)//3\n", - " \n", - " # drop features\n", - " df_feat = df_feat.drop(['Open','Close','High','Low', 'Volume', 'Date'], axis=1)\n", - "\n", - " # fill nan values with 0\n", - " df_feat = df_feat.fillna(0)\n", - "\n", - " return df_feat\n", - " \n", - " # create your features dataframe for each asset and concatenate\n", - " feature_df = pd.DataFrame()\n", - " for i in range(14):\n", - " print(i)\n", - " feature_df = pd.concat([feature_df,get_features(df_train,i,train=True)])\n", - " \n", - " # save the feature engineered data as a pickle file to be used by the modeling component.\n", - " with open(f'{data_path}/feature_df', 'wb') as f:\n", - " pickle.dump(feature_df, f)\n", - " \n", - " return(print('Done!')) " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Merge Assets Data and Features" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "# merge_assets_features step\n", - "\n", - "def merge_assets_features(data_path):\n", - " \n", - " # install the necessary libraries\n", - " import sys, subprocess;\n", - " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", - " \n", - " # import Library\n", - " import os, pickle;\n", - " import pandas as pd\n", - "\n", - " #loading the feature_df data\n", - " with open(f'{data_path}/feature_df', 'rb') as f:\n", - " feature_df = pickle.load(f)\n", - " \n", - " #loading the df_asset_details data\n", - " with open(f'{data_path}/df_asset_details', 'rb') as g:\n", - " df_asset_details = pickle.load(g)\n", - " \n", - " # assign weight column feature dataframe\n", - " feature_df = pd.merge(feature_df, df_asset_details[['Asset_ID','Weight']], how='left', on=['Asset_ID'])\n", - "\n", - " #Save the feature_df as a pickle file to be used by the modelling component.\n", - " with open(f'{data_path}/merge_feature_df', 'wb') as h:\n", - " pickle.dump(feature_df, h)\n", - " \n", - " return(print('Done!')) " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.01421, - "end_time": "2022-04-17T07:17:13.396620", - "exception": false, - "start_time": "2022-04-17T07:17:13.382410", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "## Modelling\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "# modeling step\n", - "\n", - "def modeling(data_path):\n", - " \n", - " # install the necessary libraries\n", - " import sys, subprocess;\n", - " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','lightgbm'])\n", - " \n", - " # import Library\n", - " import os, pickle, joblib;\n", - " import pandas as pd\n", - " import numpy as np\n", - " import lightgbm as lgb\n", - " from lightgbm import LGBMRegressor\n", - "\n", - " #loading the new_feats data\n", - " with open(f'{data_path}/merge_feature_df', 'rb') as f:\n", - " feature_df = pickle.load(f)\n", - " \n", - " # define features for LGBM\n", - " features = ['Asset_ID', 'RSI_30', 'ATR_30',\n", - " 'DEMA_30', 'RSI_120', 'ATR_120', 'DEMA_120', 'RSI_240', 'ATR_240',\n", - " 'DEMA_240', 'sma_30', 'return_30', 'sma_120', 'return_120', 'sma_240',\n", - " 'return_240', 'HL', 'OC', 'lower_shadow', 'upper_shadow', 'Day',\n", - " 'dayofyear', 'weekofyear', 'season']\n", - " categoricals = ['Asset_ID']\n", - " \n", - " # define the evaluation metric\n", - " def weighted_correlation(a, train_data):\n", - "\n", - " weights = train_data.add_w.values.flatten()\n", - " b = train_data.get_label()\n", - "\n", - "\n", - " w = np.ravel(weights)\n", - " a = np.ravel(a)\n", - " b = np.ravel(b)\n", - "\n", - " sum_w = np.sum(w)\n", - " mean_a = np.sum(a * w) / sum_w\n", - " mean_b = np.sum(b * w) / sum_w\n", - " var_a = np.sum(w * np.square(a - mean_a)) / sum_w\n", - " var_b = np.sum(w * np.square(b - mean_b)) / sum_w\n", - "\n", - " cov = np.sum((a * b * w)) / np.sum(w) - mean_a * mean_b\n", - " corr = cov / np.sqrt(var_a * var_b)\n", - "\n", - " return 'eval_wcorr', corr, True\n", - " \n", - " # define train and validation weights and datasets\n", - " weights_train = feature_df.query('train_flg == 1')[['Weight']]\n", - " weights_test = feature_df.query('train_flg == 0')[['Weight']]\n", - "\n", - " train_dataset = lgb.Dataset(feature_df.query('train_flg == 1')[features], \n", - " feature_df.query('train_flg == 1')['Target'].values, \n", - " feature_name = features,\n", - " categorical_feature= categoricals)\n", - " val_dataset = lgb.Dataset(feature_df.query('train_flg == 0')[features], \n", - " feature_df.query('train_flg == 0')['Target'].values, \n", - " feature_name = features,\n", - " categorical_feature= categoricals)\n", - " # add weights\n", - " train_dataset.add_w = weights_train\n", - " val_dataset.add_w = weights_test\n", - " \n", - " # LGBM params\n", - " evals_result = {}\n", - " params = {'n_estimators': 1200,\n", - " 'objective': 'regression',\n", - " 'metric': 'rmse',\n", - " 'boosting_type': 'gbdt',\n", - " 'max_depth': -1, \n", - " 'learning_rate': 0.01,\n", - " 'seed': 2022,\n", - " 'verbose': -1,\n", - " }\n", - "\n", - " # train LGBM\n", - " model = lgb.train(params = params,\n", - " train_set = train_dataset, \n", - " valid_sets = [val_dataset],\n", - " early_stopping_rounds=60,\n", - " verbose_eval = 30,\n", - " feval=weighted_correlation,\n", - " evals_result = evals_result \n", - " )\n", - " \n", - " # saving model\n", - " joblib.dump(model, f'{data_path}/lgb.jl')\n", - " \n", - " return(print('Done!')) " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.01428, - "end_time": "2022-04-17T07:17:23.959655", - "exception": false, - "start_time": "2022-04-17T07:17:23.945375", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "## Evaluation" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "# evaluation step\n", - "\n", - "def evaluation_result(data_path, \n", - " metrics_path: OutputPath(str)) -> NamedTuple(\"EvaluationOutput\", [(\"mlpipeline_metrics\", \"Metrics\")]):\n", - " \n", - " # import Library\n", - " import sys, subprocess;\n", - " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','lightgbm'])\n", - " import json;\n", - " from collections import namedtuple\n", - " import joblib\n", - " import lightgbm as lgb\n", - " from lightgbm import LGBMRegressor\n", - " \n", - " # load model\n", - " model = joblib.load(f'{data_path}/lgb.jl')\n", - "\n", - " # model evaluation\n", - " root_mean_squared_error = model.best_score.get('valid_0').get('rmse')\n", - " weighted_correlation = model.best_score.get('valid_0').get('eval_wcorr')\n", - " \n", - " # create kubeflow metric metadata for UI \n", - " metrics = {\n", - " 'metrics': [\n", - " {'name': 'root-mean-squared-error',\n", - " 'numberValue': root_mean_squared_error,\n", - " 'format': 'RAW'},\n", - " {'name': 'weighted-correlation',\n", - " 'numberValue': weighted_correlation,\n", - " 'format': 'RAW'}\n", - " ]\n", - " }\n", - " \n", - "\n", - " with open(metrics_path, \"w\") as f:\n", - " json.dump(metrics, f)\n", - "\n", - " output_tuple = namedtuple(\"EvaluationOutput\", [\"mlpipeline_metrics\"])\n", - "\n", - " return output_tuple(json.dumps(metrics))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create pipeline components \n", - "\n", - "using `create_component_from_func`" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "# create light weight components\n", - "download_op = comp.create_component_from_func(download_data,base_image=\"python:3.7.1\")\n", - "load_op = comp.create_component_from_func(load_data,base_image=\"python:3.7.1\")\n", - "merge_assets_features_op = comp.create_component_from_func(merge_assets_features,base_image=\"python:3.7.1\")\n", - "feature_eng_op = comp.create_component_from_func(feature_engineering,base_image=\"python:3.7.1\")\n", - "modeling_op = comp.create_component_from_func(modeling, base_image=\"python:3.7.1\")\n", - "evaluation_op = comp.create_component_from_func(evaluation_result, base_image=\"python:3.7.1\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Kubeflow pipeline creation" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "# define pipeline\n", - "@dsl.pipeline(name=\"g-research-crypto-forecasting-pipeline\", \n", - " description=\"Forecasting short term returns in 14 popular cryptocurrencies.\")\n", - "\n", - "# Define parameters to be fed into pipeline\n", - "def g_research_crypto_forecast_pipeline(\n", - " dataset: str,\n", - " data_path: str\n", - " ):\n", - " # Define volume to share data between components.\n", - " vop = dsl.VolumeOp(\n", - " name=\"create_data_volume\",\n", - " resource_name=\"data-volume\", \n", - " size=\"16Gi\", \n", - " modes=dsl.VOLUME_MODE_RWO)\n", - " \n", - " \n", - " # Create download container.\n", - " download_container = download_op(dataset, data_path)\\\n", - " .add_pvolumes({data_path: vop.volume}).add_pod_label(\"kaggle-secret\", \"true\")\n", - " # Create load container.\n", - " load_container = load_op(data_path)\\\n", - " .add_pvolumes({data_path: download_container.pvolume})\n", - " # Create feature engineering container.\n", - " feat_eng_container = feature_eng_op(data_path)\\\n", - " .add_pvolumes({data_path: load_container.pvolume})\n", - " # Create merge_assets_feat container.\n", - " merge_assets_feat_container = merge_assets_features_op(data_path)\\\n", - " .add_pvolumes({data_path: feat_eng_container.pvolume})\n", - " # Create modeling container.\n", - " modeling_container = modeling_op(data_path)\\\n", - " .add_pvolumes({data_path: merge_assets_feat_container.pvolume})\n", - " # Create prediction container.\n", - " evaluation_container = evaluation_op(data_path).add_pvolumes({data_path: modeling_container.pvolume})" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "# create client that would enable communication with the Pipelines API server \n", - "client = kfp.Client()" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "# arguments\n", - "dataset = \"g-research-crypto-forecasting\"\n", - "data_path = \"/mnt\"" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "Experiment details." - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "Run details." - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "pipeline_func = g_research_crypto_forecast_pipeline\n", - "\n", - "experiment_name = 'g_research_crypto_forecast_pipeline_lightweight'\n", - "run_name = pipeline_func.__name__ + ' run'\n", - "\n", - "arguments = {\n", - " \"dataset\": dataset,\n", - " \"data_path\": data_path\n", - " }\n", - "\n", - "# Compile pipeline to generate compressed YAML definition of the pipeline.\n", - "kfp.compiler.Compiler().compile(pipeline_func, \n", - " '{}.zip'.format(experiment_name))\n", - "\n", - "# Submit pipeline directly from pipeline function\n", - "run_result = client.create_run_from_pipeline_func(pipeline_func, \n", - " experiment_name=experiment_name, \n", - " run_name=run_name, \n", - " arguments=arguments\n", - " )\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kubeflow_notebook": { - "autosnapshot": true, - "experiment": { - "id": "2efb8e27-3b2e-439b-a53c-b1f9d7b94cfc", - "name": "g-research-crypto-forecasting" - }, - "experiment_name": "g-research-crypto-forecasting", - "katib_metadata": { - "algorithm": { - "algorithmName": "grid" - }, - "maxFailedTrialCount": 3, - "maxTrialCount": 12, - "objective": { - "objectiveMetricName": "", - "type": "minimize" - }, - "parallelTrialCount": 3, - "parameters": [] - }, - "katib_run": false, - "pipeline_description": "Forecasting short term returns in 14 popular cryptocurrencies.", - "pipeline_name": "g-research-crypto-forecasting-pipeline", - "snapshot_volumes": true, - "steps_defaults": [ - "label:access-ml-pipeline:true", - "label:kaggle-secret:true", - "label:access-rok:true" - ], - "volume_access_mode": "rwm", - "volumes": [ - { - "annotations": [], - "mount_point": "/home/jovyan", - "name": "demo-workspace-fb99v", - "size": 15, - "size_type": "Gi", - "snapshot": false, - "type": "clone" - } - ] - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.9" - }, - "papermill": { - "default_parameters": {}, - "duration": 32.012084, - "end_time": "2022-04-17T07:17:25.053666", - "environment_variables": {}, - "exception": null, - "input_path": "__notebook__.ipynb", - "output_path": "__notebook__.ipynb", - "parameters": {}, - "start_time": "2022-04-17T07:16:53.041582", - "version": "2.3.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# 🪙 G-Research Crypto Kubeflow Pipeline\n", + "![](./images/vector-blockchain-poster.jpg)\n", + "\n", + "---\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "In this [Kaggle competition](https://www.kaggle.com/competitions/g-research-crypto-forecasting/overview), you'll use your machine learning expertise to forecast short term returns in 14 popular cryptocurrencies. The dataset provided contains information on historic trades for several cryptoassets, such as Bitcoin and Ethereum. \n", + "\n", + "> G-Research is a leading quantitative research and technology company. By using the latest scientific techniques, they produce world-beating predictive research and build advanced technology to analyse the world's data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Install relevant libraries\n", + "\n", + "\n", + ">Update pip `pip install --user --upgrade pip`\n", + "\n", + ">Install and upgrade kubeflow sdk `pip install kfp --upgrade --user --quiet`\n", + "\n", + "You may need to restart your notebook kernel after installing the kfp sdk" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: pip in /usr/local/lib/python3.6/dist-packages (21.3.1)\n" + ] + } + ], + "source": [ + "!pip install --user --upgrade pip" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install kfp --upgrade --user --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Name: kfp\n", + "Version: 1.8.11\n", + "Summary: KubeFlow Pipelines SDK\n", + "Home-page: https://github.com/kubeflow/pipelines\n", + "Author: The Kubeflow Authors\n", + "Author-email: \n", + "License: UNKNOWN\n", + "Location: /home/jovyan/.local/lib/python3.6/site-packages\n", + "Requires: absl-py, click, cloudpickle, dataclasses, Deprecated, docstring-parser, fire, google-api-python-client, google-auth, google-cloud-storage, jsonschema, kfp-pipeline-spec, kfp-server-api, kubernetes, protobuf, pydantic, PyYAML, requests-toolbelt, strip-hints, tabulate, typer, typing-extensions, uritemplate\n", + "Required-by: kubeflow-kale\n" + ] + } + ], + "source": [ + "# confirm the kfp sdk\n", + "! pip show kfp" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [ + "imports" + ] + }, + "outputs": [], + "source": [ + "import kfp\n", + "import kfp.components as comp\n", + "import kfp.dsl as dsl\n", + "from kfp.components import OutputPath\n", + "from typing import NamedTuple" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# Kubeflow pipeline component creation\n", + "\n", + "## Download the dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# download data step\n", + "def download_data(dataset, \n", + " data_path):\n", + " \n", + " # install the necessary libraries\n", + " import os, sys, subprocess, zipfile, pickle;\n", + " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','kaggle'])\n", + " \n", + " # import libraries\n", + " import pandas as pd\n", + "\n", + " # setup kaggle environment for data download\n", + " with open('/secret/kaggle-secret/password', 'r') as file:\n", + " kaggle_key = file.read().rstrip()\n", + " with open('/secret/kaggle-secret/username', 'r') as file:\n", + " kaggle_user = file.read().rstrip()\n", + " \n", + " os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", + " \n", + " # create data_path directory\n", + " if not os.path.exists(data_path):\n", + " os.makedirs(data_path)\n", + " \n", + " # download kaggle's g-research-crypto-forecasting data\n", + " subprocess.run([\"kaggle\",\"competitions\", \"download\", \"-c\", dataset])\n", + " \n", + " # extract 'train.csv' and 'asset_details.csv' in g-research-crypto-forecasting.zip to data_path\n", + " with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", + " zip_ref.extractall(data_path, members=['train.csv', 'asset_details.csv'])\n", + " \n", + " return(print('Done!'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Load Data" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# load data step\n", + "def load_data(data_path):\n", + " \n", + " # install the necessary libraries\n", + " import os, sys, subprocess, pickle;\n", + " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", + " \n", + " # import libraries\n", + " import pandas as pd\n", + "\n", + " TRAIN_CSV = f'{data_path}/train.csv'\n", + " ASSET_DETAILS_CSV = f'{data_path}/asset_details.csv'\n", + " \n", + " # read TRAIN_CSV and ASSET_DETAILS_CSV\n", + " df_train = pd.read_csv(TRAIN_CSV)\n", + " df_asset_details = pd.read_csv(ASSET_DETAILS_CSV).sort_values(\"Asset_ID\")\n", + " \n", + " df_train['datetime'] = pd.to_datetime(df_train['timestamp'], unit='s')\n", + " df_train = df_train[df_train['datetime'] >= '2020-01-01 00:00:00'].copy()\n", + " \n", + " # Save the df_train data as a pickle file to be used by the feature_engineering component.\n", + " with open(f'{data_path}/df_train', 'wb') as f:\n", + " pickle.dump(df_train, f)\n", + " \n", + " # Save the df_train data as a pickle file to be used by the merge_data component.\n", + " with open(f'{data_path}/df_asset_details', 'wb') as g:\n", + " pickle.dump(df_asset_details, g)\n", + "\n", + " \n", + " return(print('Done!'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Feature Engineering" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# feature engineering step\n", + "\n", + "def feature_engineering(data_path):\n", + " \n", + " # install the necessary libraries\n", + " import sys, subprocess;\n", + " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','tqdm'])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','talib-binary'])\n", + " \n", + " # import Library\n", + " import os, pickle, time, talib, datetime;\n", + " import numpy as np\n", + " import pandas as pd\n", + " from tqdm import tqdm\n", + "\n", + " # loading the df_train data\n", + " with open(f'{data_path}/df_train', 'rb') as f:\n", + " df_train = pickle.load(f)\n", + " \n", + " # creating technical indicators\n", + " \n", + " # Create a function to calculate the Relative Strength Index\n", + " def RSI(df, n):\n", + " return talib.RSI(df['Close'], n)\n", + " \n", + " # Create a function to calculate the Average True Range\n", + " def ATR(df, n):\n", + " return talib.ATR(df[\"High\"], df.Low, df.Close, n)\n", + "\n", + " # Create a function to calculate the Double Exponential Moving Average (DEMA)\n", + " def DEMA(data, time_period):\n", + " #Calculate the Exponential Moving Average for some time_period (in days)\n", + " EMA = data['Close'].ewm(span=time_period, adjust=False).mean()\n", + " #Calculate the DEMA\n", + " DEMA = 2*EMA - EMA.ewm(span=time_period, adjust=False).mean()\n", + " return DEMA\n", + " \n", + " # Create a function to calculate the upper_shadow\n", + " def upper_shadow(df):\n", + " return df['High'] - np.maximum(df['Close'], df['Open'])\n", + " \n", + " # Create a function to calculate the lower_shadow\n", + " def lower_shadow(df):\n", + " return np.minimum(df['Close'], df['Open']) - df['Low']\n", + " \n", + " \n", + " def get_features(df, asset_id, train=True):\n", + " '''\n", + " This function takes a dataframe with all asset data and return the lagged features for a single asset.\n", + "\n", + " df - Full dataframe with all assets included\n", + " asset_id - integer from 0-13 inclusive to represent a cryptocurrency asset\n", + " train - True - you are training your model\n", + " - False - you are submitting your model via api\n", + " '''\n", + " # filter based on asset id\n", + " df = df[df['Asset_ID']==asset_id]\n", + "\n", + " # sort based on time stamp\n", + " df = df.sort_values('timestamp')\n", + "\n", + " if train == True:\n", + " df_feat = df.copy()\n", + "\n", + " # define a train_flg column to split your data into train and validation\n", + " totimestamp = lambda s: np.int32(time.mktime(datetime.datetime.strptime(s, \"%d/%m/%Y\").timetuple()))\n", + " valid_window = [totimestamp(\"01/05/2021\")]\n", + "\n", + " df_feat['train_flg'] = np.where(df_feat['timestamp']>=valid_window[0], 0,1)\n", + " df_feat = df_feat[['timestamp','Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','Target','train_flg']].copy()\n", + " else:\n", + " df = df.sort_values('row_id')\n", + " df_feat = df[['Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','row_id']].copy()\n", + "\n", + " for i in tqdm([30, 120, 240]):\n", + " # Applyin technical indicators\n", + " df_feat[f'RSI_{i}'] = RSI(df_feat, i)\n", + " df_feat[f'ATR_{i}'] = ATR(df_feat, i)\n", + " df_feat[f'DEMA_{i}'] = DEMA(df_feat, i)\n", + "\n", + " for i in tqdm([30, 120, 240]):\n", + " # creating lag features\n", + " df_feat[f'sma_{i}'] = df_feat['Close'].rolling(i).mean()/df_feat['Close'] -1\n", + " df_feat[f'return_{i}'] = df_feat['Close']/df_feat['Close'].shift(i) -1\n", + "\n", + " # new features\n", + " df_feat['HL'] = np.log(df_feat['High'] - df_feat['Low'])\n", + " df_feat['OC'] = np.log(df_feat['Close'] - df_feat['Open'])\n", + " \n", + " # Applyin lower_shadow and upper_shadow indicators\n", + " df_feat['lower_shadow'] = np.log(lower_shadow(df)) \n", + " df_feat['upper_shadow'] = np.log(upper_shadow(df))\n", + "\n", + " # replace inf with nan\n", + " df_feat.replace([np.inf, -np.inf], np.nan, inplace=True)\n", + "\n", + " # datetime features\n", + " df_feat['Date'] = pd.to_datetime(df_feat['timestamp'], unit='s')\n", + " df_feat['Day'] = df_feat['Date'].dt.weekday.astype(np.int32)\n", + " df_feat[\"dayofyear\"] = df_feat['Date'].dt.dayofyear\n", + " df_feat[\"weekofyear\"] = df_feat['Date'].dt.weekofyear\n", + " df_feat[\"season\"] = ((df_feat['Date'].dt.month)%12 + 3)//3\n", + " \n", + " # drop features\n", + " df_feat = df_feat.drop(['Open','Close','High','Low', 'Volume', 'Date'], axis=1)\n", + "\n", + " # fill nan values with 0\n", + " df_feat = df_feat.fillna(0)\n", + "\n", + " return df_feat\n", + " \n", + " # create your features dataframe for each asset and concatenate\n", + " feature_df = pd.DataFrame()\n", + " for i in range(14):\n", + " print(i)\n", + " feature_df = pd.concat([feature_df,get_features(df_train,i,train=True)])\n", + " \n", + " # save the feature engineered data as a pickle file to be used by the modeling component.\n", + " with open(f'{data_path}/feature_df', 'wb') as f:\n", + " pickle.dump(feature_df, f)\n", + " \n", + " return(print('Done!')) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Merge Assets Data and Features" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# merge_assets_features step\n", + "\n", + "def merge_assets_features(data_path):\n", + " \n", + " # install the necessary libraries\n", + " import sys, subprocess;\n", + " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", + " \n", + " # import Library\n", + " import os, pickle;\n", + " import pandas as pd\n", + "\n", + " #loading the feature_df data\n", + " with open(f'{data_path}/feature_df', 'rb') as f:\n", + " feature_df = pickle.load(f)\n", + " \n", + " #loading the df_asset_details data\n", + " with open(f'{data_path}/df_asset_details', 'rb') as g:\n", + " df_asset_details = pickle.load(g)\n", + " \n", + " # assign weight column feature dataframe\n", + " feature_df = pd.merge(feature_df, df_asset_details[['Asset_ID','Weight']], how='left', on=['Asset_ID'])\n", + "\n", + " #Save the feature_df as a pickle file to be used by the modelling component.\n", + " with open(f'{data_path}/merge_feature_df', 'wb') as h:\n", + " pickle.dump(feature_df, h)\n", + " \n", + " return(print('Done!')) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "papermill": { + "duration": 0.01421, + "end_time": "2022-04-17T07:17:13.396620", + "exception": false, + "start_time": "2022-04-17T07:17:13.382410", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "## Modelling\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# modeling step\n", + "\n", + "def modeling(data_path):\n", + " \n", + " # install the necessary libraries\n", + " import sys, subprocess;\n", + " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','lightgbm'])\n", + " \n", + " # import Library\n", + " import os, pickle, joblib;\n", + " import pandas as pd\n", + " import numpy as np\n", + " import lightgbm as lgb\n", + " from lightgbm import LGBMRegressor\n", + "\n", + " #loading the new_feats data\n", + " with open(f'{data_path}/merge_feature_df', 'rb') as f:\n", + " feature_df = pickle.load(f)\n", + " \n", + " # define features for LGBM\n", + " features = ['Asset_ID', 'RSI_30', 'ATR_30',\n", + " 'DEMA_30', 'RSI_120', 'ATR_120', 'DEMA_120', 'RSI_240', 'ATR_240',\n", + " 'DEMA_240', 'sma_30', 'return_30', 'sma_120', 'return_120', 'sma_240',\n", + " 'return_240', 'HL', 'OC', 'lower_shadow', 'upper_shadow', 'Day',\n", + " 'dayofyear', 'weekofyear', 'season']\n", + " categoricals = ['Asset_ID']\n", + " \n", + " # define the evaluation metric\n", + " def weighted_correlation(a, train_data):\n", + "\n", + " weights = train_data.add_w.values.flatten()\n", + " b = train_data.get_label()\n", + "\n", + "\n", + " w = np.ravel(weights)\n", + " a = np.ravel(a)\n", + " b = np.ravel(b)\n", + "\n", + " sum_w = np.sum(w)\n", + " mean_a = np.sum(a * w) / sum_w\n", + " mean_b = np.sum(b * w) / sum_w\n", + " var_a = np.sum(w * np.square(a - mean_a)) / sum_w\n", + " var_b = np.sum(w * np.square(b - mean_b)) / sum_w\n", + "\n", + " cov = np.sum((a * b * w)) / np.sum(w) - mean_a * mean_b\n", + " corr = cov / np.sqrt(var_a * var_b)\n", + "\n", + " return 'eval_wcorr', corr, True\n", + " \n", + " # define train and validation weights and datasets\n", + " weights_train = feature_df.query('train_flg == 1')[['Weight']]\n", + " weights_test = feature_df.query('train_flg == 0')[['Weight']]\n", + "\n", + " train_dataset = lgb.Dataset(feature_df.query('train_flg == 1')[features], \n", + " feature_df.query('train_flg == 1')['Target'].values, \n", + " feature_name = features,\n", + " categorical_feature= categoricals)\n", + " val_dataset = lgb.Dataset(feature_df.query('train_flg == 0')[features], \n", + " feature_df.query('train_flg == 0')['Target'].values, \n", + " feature_name = features,\n", + " categorical_feature= categoricals)\n", + " # add weights\n", + " train_dataset.add_w = weights_train\n", + " val_dataset.add_w = weights_test\n", + " \n", + " # LGBM params\n", + " evals_result = {}\n", + " params = {'n_estimators': 1200,\n", + " 'objective': 'regression',\n", + " 'metric': 'rmse',\n", + " 'boosting_type': 'gbdt',\n", + " 'max_depth': -1, \n", + " 'learning_rate': 0.01,\n", + " 'seed': 2022,\n", + " 'verbose': -1,\n", + " }\n", + "\n", + " # train LGBM\n", + " model = lgb.train(params = params,\n", + " train_set = train_dataset, \n", + " valid_sets = [val_dataset],\n", + " early_stopping_rounds=60,\n", + " verbose_eval = 30,\n", + " feval=weighted_correlation,\n", + " evals_result = evals_result \n", + " )\n", + " \n", + " # saving model\n", + " joblib.dump(model, f'{data_path}/lgb.jl')\n", + " \n", + " return(print('Done!')) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "papermill": { + "duration": 0.01428, + "end_time": "2022-04-17T07:17:23.959655", + "exception": false, + "start_time": "2022-04-17T07:17:23.945375", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "## Evaluation" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# evaluation step\n", + "\n", + "def evaluation_result(data_path, \n", + " metrics_path: OutputPath(str)) -> NamedTuple(\"EvaluationOutput\", [(\"mlpipeline_metrics\", \"Metrics\")]):\n", + " \n", + " # import Library\n", + " import sys, subprocess;\n", + " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','lightgbm'])\n", + " import json;\n", + " from collections import namedtuple\n", + " import joblib\n", + " import lightgbm as lgb\n", + " from lightgbm import LGBMRegressor\n", + " \n", + " # load model\n", + " model = joblib.load(f'{data_path}/lgb.jl')\n", + "\n", + " # model evaluation\n", + " root_mean_squared_error = model.best_score.get('valid_0').get('rmse')\n", + " weighted_correlation = model.best_score.get('valid_0').get('eval_wcorr')\n", + " \n", + " # create kubeflow metric metadata for UI \n", + " metrics = {\n", + " 'metrics': [\n", + " {'name': 'root-mean-squared-error',\n", + " 'numberValue': root_mean_squared_error,\n", + " 'format': 'RAW'},\n", + " {'name': 'weighted-correlation',\n", + " 'numberValue': weighted_correlation,\n", + " 'format': 'RAW'}\n", + " ]\n", + " }\n", + " \n", + "\n", + " with open(metrics_path, \"w\") as f:\n", + " json.dump(metrics, f)\n", + "\n", + " output_tuple = namedtuple(\"EvaluationOutput\", [\"mlpipeline_metrics\"])\n", + "\n", + " return output_tuple(json.dumps(metrics))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create pipeline components \n", + "\n", + "using `create_component_from_func`" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# create light weight components\n", + "download_op = comp.create_component_from_func(download_data,base_image=\"python:3.7.1\")\n", + "load_op = comp.create_component_from_func(load_data,base_image=\"python:3.7.1\")\n", + "merge_assets_features_op = comp.create_component_from_func(merge_assets_features,base_image=\"python:3.7.1\")\n", + "feature_eng_op = comp.create_component_from_func(feature_engineering,base_image=\"python:3.7.1\")\n", + "modeling_op = comp.create_component_from_func(modeling, base_image=\"python:3.7.1\")\n", + "evaluation_op = comp.create_component_from_func(evaluation_result, base_image=\"python:3.7.1\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Kubeflow pipeline creation" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# define pipeline\n", + "@dsl.pipeline(name=\"g-research-crypto-forecasting-pipeline\", \n", + " description=\"Forecasting short term returns in 14 popular cryptocurrencies.\")\n", + "\n", + "# Define parameters to be fed into pipeline\n", + "def g_research_crypto_forecast_pipeline(\n", + " dataset: str,\n", + " data_path: str\n", + " ):\n", + " # Define volume to share data between components.\n", + " vop = dsl.VolumeOp(\n", + " name=\"create_data_volume\",\n", + " resource_name=\"data-volume\", \n", + " size=\"16Gi\", \n", + " modes=dsl.VOLUME_MODE_RWO)\n", + " \n", + " \n", + " # Create download container.\n", + " download_container = download_op(dataset, data_path)\\\n", + " .add_pvolumes({data_path: vop.volume}).add_pod_label(\"kaggle-secret\", \"true\")\n", + " # Create load container.\n", + " load_container = load_op(data_path)\\\n", + " .add_pvolumes({data_path: download_container.pvolume})\n", + " # Create feature engineering container.\n", + " feat_eng_container = feature_eng_op(data_path)\\\n", + " .add_pvolumes({data_path: load_container.pvolume})\n", + " # Create merge_assets_feat container.\n", + " merge_assets_feat_container = merge_assets_features_op(data_path)\\\n", + " .add_pvolumes({data_path: feat_eng_container.pvolume})\n", + " # Create modeling container.\n", + " modeling_container = modeling_op(data_path)\\\n", + " .add_pvolumes({data_path: merge_assets_feat_container.pvolume})\n", + " # Create prediction container.\n", + " evaluation_container = evaluation_op(data_path).add_pvolumes({data_path: modeling_container.pvolume})" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# create client that would enable communication with the Pipelines API server \n", + "client = kfp.Client()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# arguments\n", + "dataset = \"g-research-crypto-forecasting\"\n", + "data_path = \"/mnt\"" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Experiment details." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Run details." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "pipeline_func = g_research_crypto_forecast_pipeline\n", + "\n", + "experiment_name = 'g_research_crypto_forecast_pipeline_lightweight'\n", + "run_name = pipeline_func.__name__ + ' run'\n", + "\n", + "arguments = {\n", + " \"dataset\": dataset,\n", + " \"data_path\": data_path\n", + " }\n", + "\n", + "# Compile pipeline to generate compressed YAML definition of the pipeline.\n", + "kfp.compiler.Compiler().compile(pipeline_func, \n", + " '{}.zip'.format(experiment_name))\n", + "\n", + "# Submit pipeline directly from pipeline function\n", + "run_result = client.create_run_from_pipeline_func(pipeline_func, \n", + " experiment_name=experiment_name, \n", + " run_name=run_name, \n", + " arguments=arguments\n", + " )\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "kubeflow_notebook": { + "autosnapshot": true, + "experiment": { + "id": "2efb8e27-3b2e-439b-a53c-b1f9d7b94cfc", + "name": "g-research-crypto-forecasting" + }, + "experiment_name": "g-research-crypto-forecasting", + "katib_metadata": { + "algorithm": { + "algorithmName": "grid" + }, + "maxFailedTrialCount": 3, + "maxTrialCount": 12, + "objective": { + "objectiveMetricName": "", + "type": "minimize" + }, + "parallelTrialCount": 3, + "parameters": [] + }, + "katib_run": false, + "pipeline_description": "Forecasting short term returns in 14 popular cryptocurrencies.", + "pipeline_name": "g-research-crypto-forecasting-pipeline", + "snapshot_volumes": true, + "steps_defaults": [ + "label:access-ml-pipeline:true", + "label:kaggle-secret:true", + "label:access-rok:true" + ], + "volume_access_mode": "rwm", + "volumes": [ + { + "annotations": [], + "mount_point": "/home/jovyan", + "name": "demo-workspace-fb99v", + "size": 15, + "size_type": "Gi", + "snapshot": false, + "type": "clone" + } + ] + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.9" + }, + "papermill": { + "default_parameters": {}, + "duration": 32.012084, + "end_time": "2022-04-17T07:17:25.053666", + "environment_variables": {}, + "exception": null, + "input_path": "__notebook__.ipynb", + "output_path": "__notebook__.ipynb", + "parameters": {}, + "start_time": "2022-04-17T07:16:53.041582", + "version": "2.3.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-orig.ipynb b/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-orig.ipynb index f2e89f3e1..8245400ca 100644 --- a/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-orig.ipynb +++ b/G-research-crypto-forecasting-kaggle-competition/g-research-crypto-forecast-orig.ipynb @@ -1,1013 +1,1013 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "# 🪙 G-Research Crypto Original Notebook\n", - "![](./images/vector-blockchain-poster.jpg)\n", - "\n", - "---\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "In this [Kaggle competition](https://www.kaggle.com/competitions/g-research-crypto-forecasting/overview), you'll use your machine learning expertise to forecast short term returns in 14 popular cryptocurrencies. The dataset provided contains information on historic trades for several cryptoassets, such as Bitcoin and Ethereum. \n", - "\n", - "> G-Research is a leading quantitative research and technology company. By using the latest scientific techniques, they produce world-beating predictive research and build advanced technology to analyse the world's data." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Install necessary packages\n", - "\n", - "We can install the necessary package by either running pip install --user or include everything in a requirements.txt file and run pip install --user -r requirements.txt. We have put the dependencies in a requirements.txt file so we will use the former method.\n", - "\n", - "NOTE: After installing python packages, restart notebook kernel before proceeding." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "!pip install -r requirements.txt --user --quiet" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Imports\n", - "\n", - "In this section we import the packages we need for this example. Make it a habit to gather your imports in a single place. It will make your life easier if you are going to transform this notebook into a Kubeflow pipeline using Kale." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "tags": [ - "imports" - ] - }, - "outputs": [], - "source": [ - "import os, random, subprocess\n", - "import pandas as pd\n", - "import numpy as np\n", - "import time, datetime, zipfile\n", - "import joblib, talib\n", - "from tqdm import tqdm\n", - "import lightgbm as lgb\n", - "\n", - "import warnings\n", - "warnings.filterwarnings(\"ignore\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Project hyper-parameters\n", - "\n", - "In this cell, we define the different hyper-parameters. Defining them in one place makes it easier to experiment with their values and also facilitates the execution of HP Tuning experiments using Kale and Katib." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "tags": [ - "pipeline-parameters" - ] - }, - "outputs": [], - "source": [ - "# Hyper-parameters\n", - "LR = 0.01\n", - "N_EST = 1200" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "Set random seed for reproducibility" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "def fix_all_seeds(seed):\n", - " np.random.seed(seed)\n", - " random.seed(seed)\n", - " os.environ['PYTHONHASHSEED'] = str(seed)\n", - "\n", - "fix_all_seeds(2022)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Download data\n", - "\n", - "In this section, we download the data from kaggle using the Kaggle API credentials" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "tags": [ - "block:download_data" - ] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "CompletedProcess(args=['kaggle', 'competitions', 'download', '-c', 'g-research-crypto-forecasting'], returncode=0)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# setup kaggle environment for data download\n", - "dataset = \"g-research-crypto-forecasting\"\n", - "\n", - "# setup kaggle environment for data download\n", - "with open('/secret/kaggle-secret/password', 'r') as file:\n", - " kaggle_key = file.read().rstrip()\n", - "with open('/secret/kaggle-secret/username', 'r') as file:\n", - " kaggle_user = file.read().rstrip()\n", - "\n", - "os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", - "\n", - "# download kaggle's g-research-crypto-forecast data\n", - "subprocess.run([\"kaggle\",\"competitions\", \"download\", \"-c\", dataset])" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "tags": [ - "block:" - ] - }, - "outputs": [], - "source": [ - "# path to download to\n", - "data_path = 'data'\n", - "\n", - "# extract g-research-crypto-forecasting.zip to load_data_path\n", - "with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", - " zip_ref.extractall(data_path, members=['train.csv', 'asset_details.csv'])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Load the dataset\n", - "\n", - "First, let us load and analyze the data.\n", - "\n", - "The data is in csv format, thus, we use the handy read_csv pandas method." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "tags": [ - "block:load_data", - "prev:download_data" - ] - }, - "outputs": [], - "source": [ - "TRAIN_CSV = f'{data_path}/train.csv'\n", - "ASSET_DETAILS_CSV = f'{data_path}/asset_details.csv'" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "df_train = pd.read_csv(TRAIN_CSV)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(24236806, 10)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Asset_IDWeightAsset_Name
104.304065Binance Coin
216.779922Bitcoin
022.397895Bitcoin Cash
1034.406719Cardano
1343.555348Dogecoin
351.386294EOS.IO
565.894403Ethereum
472.079442Ethereum Classic
1181.098612IOTA
692.397895Litecoin
12101.098612Maker
7111.609438Monero
9122.079442Stellar
8131.791759TRON
\n", - "
" - ], - "text/plain": [ - " Asset_ID Weight Asset_Name\n", - "1 0 4.304065 Binance Coin\n", - "2 1 6.779922 Bitcoin\n", - "0 2 2.397895 Bitcoin Cash\n", - "10 3 4.406719 Cardano\n", - "13 4 3.555348 Dogecoin\n", - "3 5 1.386294 EOS.IO\n", - "5 6 5.894403 Ethereum\n", - "4 7 2.079442 Ethereum Classic\n", - "11 8 1.098612 IOTA\n", - "6 9 2.397895 Litecoin\n", - "12 10 1.098612 Maker\n", - "7 11 1.609438 Monero\n", - "9 12 2.079442 Stellar\n", - "8 13 1.791759 TRON" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_asset_details = pd.read_csv(ASSET_DETAILS_CSV).sort_values(\"Asset_ID\")\n", - "df_asset_details" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "df_train['datetime'] = pd.to_datetime(df_train['timestamp'], unit='s')\n", - "df_train = df_train[df_train['datetime'] >= '2020-01-01 00:00:00'].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(12228898, 11)" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "Timestamp('2021-09-21 00:00:00')" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train['datetime'].max()" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "timestamp 0\n", - "Asset_ID 0\n", - "Count 0\n", - "Open 0\n", - "High 0\n", - "Low 0\n", - "Close 0\n", - "Volume 0\n", - "VWAP 9\n", - "Target 262453\n", - "datetime 0\n", - "dtype: int64" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train.isna().sum()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "### Define Helper Functions" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "tags": [ - "functions" - ] - }, - "outputs": [], - "source": [ - "# define the evaluation metric\n", - "def weighted_correlation(a, train_data):\n", - " \n", - " weights = train_data.add_w.values.flatten()\n", - " b = train_data.get_label()\n", - " \n", - " \n", - " w = np.ravel(weights)\n", - " a = np.ravel(a)\n", - " b = np.ravel(b)\n", - "\n", - " sum_w = np.sum(w)\n", - " mean_a = np.sum(a * w) / sum_w\n", - " mean_b = np.sum(b * w) / sum_w\n", - " var_a = np.sum(w * np.square(a - mean_a)) / sum_w\n", - " var_b = np.sum(w * np.square(b - mean_b)) / sum_w\n", - "\n", - " cov = np.sum((a * b * w)) / np.sum(w) - mean_a * mean_b\n", - " corr = cov / np.sqrt(var_a * var_b)\n", - "\n", - " return 'eval_wcorr', corr, True" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "tags": [ - "functions" - ] - }, - "outputs": [], - "source": [ - "def RSI(df, n):\n", - " return talib.RSI(df['Close'], n)\n", - "\n", - "def ATR(df, n):\n", - " return talib.ATR(df[\"High\"], df.Low, df.Close, n)\n", - "\n", - "#Create a function to calculate the Double Exponential Moving Average (DEMA)\n", - "def DEMA(data, time_period):\n", - " #Calculate the Exponential Moving Average for some time_period (in days)\n", - " EMA = data['Close'].ewm(span=time_period, adjust=False).mean()\n", - " #Calculate the DEMA\n", - " DEMA = 2*EMA - EMA.ewm(span=time_period, adjust=False).mean()\n", - " return DEMA\n", - "\n", - "def upper_shadow(df):\n", - " return df['High'] - np.maximum(df['Close'], df['Open'])\n", - "\n", - "def lower_shadow(df):\n", - " return np.minimum(df['Close'], df['Open']) - df['Low']" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Feature Engineering" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "tags": [ - "block:feature_engineering", - "prev:load_data" - ] - }, - "outputs": [], - "source": [ - "def get_features(df, \n", - " asset_id, \n", - " train=True):\n", - " '''\n", - " This function takes a dataframe with all asset data and return the lagged features for a single asset.\n", - " \n", - " df - Full dataframe with all assets included\n", - " asset_id - integer from 0-13 inclusive to represent a cryptocurrency asset\n", - " train - True - you are training your model\n", - " - False - you are submitting your model via api\n", - " '''\n", - " # filter based on asset id\n", - " df = df[df['Asset_ID']==asset_id]\n", - " \n", - " # sort based on time stamp\n", - " df = df.sort_values('timestamp')\n", - " \n", - " if train == True:\n", - " df_feat = df.copy()\n", - " \n", - " # define a train_flg column to split your data into train and validation\n", - " totimestamp = lambda s: np.int32(time.mktime(datetime.datetime.strptime(s, \"%d/%m/%Y\").timetuple()))\n", - " valid_window = [totimestamp(\"01/05/2021\")]\n", - " \n", - " df_feat['train_flg'] = np.where(df_feat['timestamp']>=valid_window[0], 0,1)\n", - " df_feat = df_feat[['timestamp','Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','Target','train_flg']].copy()\n", - " else:\n", - " df = df.sort_values('row_id')\n", - " df_feat = df[['Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','row_id']].copy()\n", - " \n", - " for i in tqdm([30, 120, 240]):\n", - " # creating technical indicators\n", - " df_feat[f'RSI_{i}'] = RSI(df_feat, i)\n", - " df_feat[f'ATR_{i}'] = ATR(df_feat, i)\n", - " df_feat[f'DEMA_{i}'] = DEMA(df_feat, i)\n", - "\n", - " for i in tqdm([30, 120, 240]):\n", - " # creating lag features\n", - " df_feat[f'sma_{i}'] = df_feat['Close'].rolling(i).mean()/df_feat['Close'] -1\n", - " df_feat[f'return_{i}'] = df_feat['Close']/df_feat['Close'].shift(i) -1\n", - " \n", - " # new featu# creating technical indicators featureses\n", - " df_feat['HL'] = np.log(df_feat['High'] - df_feat['Low'])\n", - " df_feat['OC'] = np.log(df_feat['Close'] - df_feat['Open'])\n", - " \n", - " df_feat['lower_shadow'] = np.log(lower_shadow(df)) \n", - " df_feat['upper_shadow'] = np.log(upper_shadow(df))\n", - " \n", - " # replace inf with nan\n", - " df_feat.replace([np.inf, -np.inf], np.nan, inplace=True)\n", - " \n", - " # datetime features\n", - " df_feat['Date'] = pd.to_datetime(df_feat['timestamp'], unit='s')\n", - " df_feat['Day'] = df_feat['Date'].dt.weekday.astype(np.int32)\n", - " df_feat[\"dayofyear\"] = df_feat['Date'].dt.dayofyear\n", - " df_feat[\"weekofyear\"] = df_feat['Date'].dt.weekofyear\n", - " df_feat[\"season\"] = ((df_feat['Date'].dt.month)%12 + 3)//3\n", - "\n", - " df_feat = df_feat.drop(['Open','Close','High','Low', 'Volume', 'Date'], axis=1)\n", - " \n", - " # fill nan values with 0\n", - " df_feat = df_feat.fillna(0)\n", - " return df_feat" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 3/3 [00:00<00:00, 7.64it/s]\n", - "100%|██████████| 3/3 [00:00<00:00, 12.66it/s]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 3/3 [00:00<00:00, 7.61it/s]\n", - "100%|██████████| 3/3 [00:00<00:00, 16.32it/s]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 3/3 [00:00<00:00, 9.89it/s]\n", - "100%|██████████| 3/3 [00:00<00:00, 22.05it/s]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 3/3 [00:00<00:00, 8.52it/s]\n", - "100%|██████████| 3/3 [00:00<00:00, 17.92it/s]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 3/3 [00:00<00:00, 10.35it/s]\n", - "100%|██████████| 3/3 [00:00<00:00, 22.56it/s]\n" - ] - } - ], - "source": [ - "# create your feature dataframe for each asset and concatenate\n", - "feature_df = pd.DataFrame()\n", - "for i in range(14):\n", - " print(i)\n", - " feature_df = pd.concat([feature_df,get_features(df_train,i,train=True)])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Merge Assets Features" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "block:merge_assets_features", - "prev:load_data", - "prev:feature_engineering" - ] - }, - "outputs": [], - "source": [ - "# assign weight column feature dataframe\n", - "feature_df = pd.merge(feature_df, df_asset_details[['Asset_ID','Weight']], how='left', on=['Asset_ID'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "feature_df.columns" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Modelling" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "block:modelling", - "prev:merge_assets_features" - ] - }, - "outputs": [], - "source": [ - "# define features for LGBM\n", - "features = ['Asset_ID', 'RSI_30', 'ATR_30',\n", - " 'DEMA_30', 'RSI_120', 'ATR_120', 'DEMA_120', 'RSI_240', 'ATR_240',\n", - " 'DEMA_240', 'sma_30', 'return_30', 'sma_120', 'return_120', 'sma_240',\n", - " 'return_240', 'HL', 'OC', 'lower_shadow', 'upper_shadow', 'Day',\n", - " 'dayofyear', 'weekofyear', 'season']\n", - "categoricals = ['Asset_ID']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# define train and validation weights and datasets\n", - "weights_train = feature_df.query('train_flg == 1')[['Weight']]\n", - "weights_test = feature_df.query('train_flg == 0')[['Weight']]\n", - "\n", - "train_dataset = lgb.Dataset(feature_df.query('train_flg == 1')[features], \n", - " feature_df.query('train_flg == 1')['Target'].values, \n", - " feature_name = features,\n", - " categorical_feature= categoricals)\n", - "val_dataset = lgb.Dataset(feature_df.query('train_flg == 0')[features], \n", - " feature_df.query('train_flg == 0')['Target'].values, \n", - " feature_name = features,\n", - " categorical_feature= categoricals)\n", - "\n", - "train_dataset.add_w = weights_train\n", - "val_dataset.add_w = weights_test\n", - "\n", - "evals_result = {}\n", - "params = {'n_estimators': int(N_EST),\n", - " 'objective': 'regression',\n", - " 'metric': 'rmse',\n", - " 'boosting_type': 'gbdt',\n", - " 'max_depth': -1, \n", - " 'learning_rate': float(LR),\n", - " 'seed': 2022,\n", - " 'verbose': -1,\n", - " }\n", - "\n", - "# train LGBM2\n", - "model = lgb.train(params = params,\n", - " train_set = train_dataset, \n", - " valid_sets = [val_dataset],\n", - " early_stopping_rounds=60,\n", - " verbose_eval = 30,\n", - " feval=weighted_correlation,\n", - " evals_result = evals_result \n", - " )\n", - "\n", - "joblib.dump(model, 'lgb.jl')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "fea_imp = pd.DataFrame({'imp':model.feature_importance(), 'col': features})\n", - "fea_imp = fea_imp.sort_values(['imp', 'col'], ascending=[True, False]).iloc[-30:]\n", - "_ = fea_imp.plot(kind='barh', x='col', y='imp', figsize=(20, 10))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Evaluation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "block:evaluation_result", - "prev:modelling" - ] - }, - "outputs": [], - "source": [ - "model = joblib.load('lgb.jl')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "root_mean_squared_error = model.best_score.get('valid_0').get('rmse')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "weighted_correlation = model.best_score.get('valid_0').get('eval_wcorr')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "pipeline-metrics" - ] - }, - "outputs": [], - "source": [ - "print(root_mean_squared_error)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "pipeline-metrics" - ] - }, - "outputs": [], - "source": [ - "print(weighted_correlation)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kubeflow_notebook": { - "autosnapshot": true, - "experiment": { - "id": "2efb8e27-3b2e-439b-a53c-b1f9d7b94cfc", - "name": "g-research-crypto-forecasting" - }, - "experiment_name": "g-research-crypto-forecasting", - "katib_metadata": { - "algorithm": { - "algorithmName": "grid" - }, - "maxFailedTrialCount": 3, - "maxTrialCount": 12, - "objective": { - "objectiveMetricName": "", - "type": "minimize" - }, - "parallelTrialCount": 3, - "parameters": [] - }, - "katib_run": false, - "pipeline_description": "forecasting short term returns in 14 popular cryptocurrencies.", - "pipeline_name": "g-research-crypto-forecasting-pipeline", - "snapshot_volumes": true, - "steps_defaults": [ - "label:access-ml-pipeline:true", - "label:kaggle-secret:true", - "label:access-rok:true" - ], - "volume_access_mode": "rwm", - "volumes": [ - { - "annotations": [], - "mount_point": "/home/jovyan", - "name": "test-workspace-6lhtr", - "size": 15, - "size_type": "Gi", - "snapshot": false, - "type": "clone" - } - ] - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.9" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# 🪙 G-Research Crypto Original Notebook\n", + "![](./images/vector-blockchain-poster.jpg)\n", + "\n", + "---\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "In this [Kaggle competition](https://www.kaggle.com/competitions/g-research-crypto-forecasting/overview), you'll use your machine learning expertise to forecast short term returns in 14 popular cryptocurrencies. The dataset provided contains information on historic trades for several cryptoassets, such as Bitcoin and Ethereum. \n", + "\n", + "> G-Research is a leading quantitative research and technology company. By using the latest scientific techniques, they produce world-beating predictive research and build advanced technology to analyse the world's data." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Install necessary packages\n", + "\n", + "We can install the necessary package by either running pip install --user or include everything in a requirements.txt file and run pip install --user -r requirements.txt. We have put the dependencies in a requirements.txt file so we will use the former method.\n", + "\n", + "NOTE: After installing python packages, restart notebook kernel before proceeding." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "!pip install -r requirements.txt --user --quiet" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Imports\n", + "\n", + "In this section we import the packages we need for this example. Make it a habit to gather your imports in a single place. It will make your life easier if you are going to transform this notebook into a Kubeflow pipeline using Kale." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [ + "imports" + ] + }, + "outputs": [], + "source": [ + "import os, random, subprocess\n", + "import pandas as pd\n", + "import numpy as np\n", + "import time, datetime, zipfile\n", + "import joblib, talib\n", + "from tqdm import tqdm\n", + "import lightgbm as lgb\n", + "\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Project hyper-parameters\n", + "\n", + "In this cell, we define the different hyper-parameters. Defining them in one place makes it easier to experiment with their values and also facilitates the execution of HP Tuning experiments using Kale and Katib." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "pipeline-parameters" + ] + }, + "outputs": [], + "source": [ + "# Hyper-parameters\n", + "LR = 0.01\n", + "N_EST = 1200" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "Set random seed for reproducibility" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "def fix_all_seeds(seed):\n", + " np.random.seed(seed)\n", + " random.seed(seed)\n", + " os.environ['PYTHONHASHSEED'] = str(seed)\n", + "\n", + "fix_all_seeds(2022)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Download data\n", + "\n", + "In this section, we download the data from kaggle using the Kaggle API credentials" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [ + "block:download_data" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "CompletedProcess(args=['kaggle', 'competitions', 'download', '-c', 'g-research-crypto-forecasting'], returncode=0)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# setup kaggle environment for data download\n", + "dataset = \"g-research-crypto-forecasting\"\n", + "\n", + "# setup kaggle environment for data download\n", + "with open('/secret/kaggle-secret/password', 'r') as file:\n", + " kaggle_key = file.read().rstrip()\n", + "with open('/secret/kaggle-secret/username', 'r') as file:\n", + " kaggle_user = file.read().rstrip()\n", + "\n", + "os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", + "\n", + "# download kaggle's g-research-crypto-forecast data\n", + "subprocess.run([\"kaggle\",\"competitions\", \"download\", \"-c\", dataset])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [ + "block:" + ] + }, + "outputs": [], + "source": [ + "# path to download to\n", + "data_path = 'data'\n", + "\n", + "# extract g-research-crypto-forecasting.zip to load_data_path\n", + "with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", + " zip_ref.extractall(data_path, members=['train.csv', 'asset_details.csv'])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Load the dataset\n", + "\n", + "First, let us load and analyze the data.\n", + "\n", + "The data is in csv format, thus, we use the handy read_csv pandas method." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "block:load_data", + "prev:download_data" + ] + }, + "outputs": [], + "source": [ + "TRAIN_CSV = f'{data_path}/train.csv'\n", + "ASSET_DETAILS_CSV = f'{data_path}/asset_details.csv'" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df_train = pd.read_csv(TRAIN_CSV)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(24236806, 10)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Asset_IDWeightAsset_Name
104.304065Binance Coin
216.779922Bitcoin
022.397895Bitcoin Cash
1034.406719Cardano
1343.555348Dogecoin
351.386294EOS.IO
565.894403Ethereum
472.079442Ethereum Classic
1181.098612IOTA
692.397895Litecoin
12101.098612Maker
7111.609438Monero
9122.079442Stellar
8131.791759TRON
\n", + "
" + ], + "text/plain": [ + " Asset_ID Weight Asset_Name\n", + "1 0 4.304065 Binance Coin\n", + "2 1 6.779922 Bitcoin\n", + "0 2 2.397895 Bitcoin Cash\n", + "10 3 4.406719 Cardano\n", + "13 4 3.555348 Dogecoin\n", + "3 5 1.386294 EOS.IO\n", + "5 6 5.894403 Ethereum\n", + "4 7 2.079442 Ethereum Classic\n", + "11 8 1.098612 IOTA\n", + "6 9 2.397895 Litecoin\n", + "12 10 1.098612 Maker\n", + "7 11 1.609438 Monero\n", + "9 12 2.079442 Stellar\n", + "8 13 1.791759 TRON" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_asset_details = pd.read_csv(ASSET_DETAILS_CSV).sort_values(\"Asset_ID\")\n", + "df_asset_details" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df_train['datetime'] = pd.to_datetime(df_train['timestamp'], unit='s')\n", + "df_train = df_train[df_train['datetime'] >= '2020-01-01 00:00:00'].copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(12228898, 11)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Timestamp('2021-09-21 00:00:00')" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train['datetime'].max()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "timestamp 0\n", + "Asset_ID 0\n", + "Count 0\n", + "Open 0\n", + "High 0\n", + "Low 0\n", + "Close 0\n", + "Volume 0\n", + "VWAP 9\n", + "Target 262453\n", + "datetime 0\n", + "dtype: int64" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train.isna().sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "### Define Helper Functions" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "tags": [ + "functions" + ] + }, + "outputs": [], + "source": [ + "# define the evaluation metric\n", + "def weighted_correlation(a, train_data):\n", + " \n", + " weights = train_data.add_w.values.flatten()\n", + " b = train_data.get_label()\n", + " \n", + " \n", + " w = np.ravel(weights)\n", + " a = np.ravel(a)\n", + " b = np.ravel(b)\n", + "\n", + " sum_w = np.sum(w)\n", + " mean_a = np.sum(a * w) / sum_w\n", + " mean_b = np.sum(b * w) / sum_w\n", + " var_a = np.sum(w * np.square(a - mean_a)) / sum_w\n", + " var_b = np.sum(w * np.square(b - mean_b)) / sum_w\n", + "\n", + " cov = np.sum((a * b * w)) / np.sum(w) - mean_a * mean_b\n", + " corr = cov / np.sqrt(var_a * var_b)\n", + "\n", + " return 'eval_wcorr', corr, True" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "tags": [ + "functions" + ] + }, + "outputs": [], + "source": [ + "def RSI(df, n):\n", + " return talib.RSI(df['Close'], n)\n", + "\n", + "def ATR(df, n):\n", + " return talib.ATR(df[\"High\"], df.Low, df.Close, n)\n", + "\n", + "#Create a function to calculate the Double Exponential Moving Average (DEMA)\n", + "def DEMA(data, time_period):\n", + " #Calculate the Exponential Moving Average for some time_period (in days)\n", + " EMA = data['Close'].ewm(span=time_period, adjust=False).mean()\n", + " #Calculate the DEMA\n", + " DEMA = 2*EMA - EMA.ewm(span=time_period, adjust=False).mean()\n", + " return DEMA\n", + "\n", + "def upper_shadow(df):\n", + " return df['High'] - np.maximum(df['Close'], df['Open'])\n", + "\n", + "def lower_shadow(df):\n", + " return np.minimum(df['Close'], df['Open']) - df['Low']" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Feature Engineering" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "tags": [ + "block:feature_engineering", + "prev:load_data" + ] + }, + "outputs": [], + "source": [ + "def get_features(df, \n", + " asset_id, \n", + " train=True):\n", + " '''\n", + " This function takes a dataframe with all asset data and return the lagged features for a single asset.\n", + " \n", + " df - Full dataframe with all assets included\n", + " asset_id - integer from 0-13 inclusive to represent a cryptocurrency asset\n", + " train - True - you are training your model\n", + " - False - you are submitting your model via api\n", + " '''\n", + " # filter based on asset id\n", + " df = df[df['Asset_ID']==asset_id]\n", + " \n", + " # sort based on time stamp\n", + " df = df.sort_values('timestamp')\n", + " \n", + " if train == True:\n", + " df_feat = df.copy()\n", + " \n", + " # define a train_flg column to split your data into train and validation\n", + " totimestamp = lambda s: np.int32(time.mktime(datetime.datetime.strptime(s, \"%d/%m/%Y\").timetuple()))\n", + " valid_window = [totimestamp(\"01/05/2021\")]\n", + " \n", + " df_feat['train_flg'] = np.where(df_feat['timestamp']>=valid_window[0], 0,1)\n", + " df_feat = df_feat[['timestamp','Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','Target','train_flg']].copy()\n", + " else:\n", + " df = df.sort_values('row_id')\n", + " df_feat = df[['Asset_ID', 'High', 'Low', 'Open', 'Close', 'Volume','row_id']].copy()\n", + " \n", + " for i in tqdm([30, 120, 240]):\n", + " # creating technical indicators\n", + " df_feat[f'RSI_{i}'] = RSI(df_feat, i)\n", + " df_feat[f'ATR_{i}'] = ATR(df_feat, i)\n", + " df_feat[f'DEMA_{i}'] = DEMA(df_feat, i)\n", + "\n", + " for i in tqdm([30, 120, 240]):\n", + " # creating lag features\n", + " df_feat[f'sma_{i}'] = df_feat['Close'].rolling(i).mean()/df_feat['Close'] -1\n", + " df_feat[f'return_{i}'] = df_feat['Close']/df_feat['Close'].shift(i) -1\n", + " \n", + " # new featu# creating technical indicators featureses\n", + " df_feat['HL'] = np.log(df_feat['High'] - df_feat['Low'])\n", + " df_feat['OC'] = np.log(df_feat['Close'] - df_feat['Open'])\n", + " \n", + " df_feat['lower_shadow'] = np.log(lower_shadow(df)) \n", + " df_feat['upper_shadow'] = np.log(upper_shadow(df))\n", + " \n", + " # replace inf with nan\n", + " df_feat.replace([np.inf, -np.inf], np.nan, inplace=True)\n", + " \n", + " # datetime features\n", + " df_feat['Date'] = pd.to_datetime(df_feat['timestamp'], unit='s')\n", + " df_feat['Day'] = df_feat['Date'].dt.weekday.astype(np.int32)\n", + " df_feat[\"dayofyear\"] = df_feat['Date'].dt.dayofyear\n", + " df_feat[\"weekofyear\"] = df_feat['Date'].dt.weekofyear\n", + " df_feat[\"season\"] = ((df_feat['Date'].dt.month)%12 + 3)//3\n", + "\n", + " df_feat = df_feat.drop(['Open','Close','High','Low', 'Volume', 'Date'], axis=1)\n", + " \n", + " # fill nan values with 0\n", + " df_feat = df_feat.fillna(0)\n", + " return df_feat" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 3/3 [00:00<00:00, 7.64it/s]\n", + "100%|██████████| 3/3 [00:00<00:00, 12.66it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 3/3 [00:00<00:00, 7.61it/s]\n", + "100%|██████████| 3/3 [00:00<00:00, 16.32it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 3/3 [00:00<00:00, 9.89it/s]\n", + "100%|██████████| 3/3 [00:00<00:00, 22.05it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 3/3 [00:00<00:00, 8.52it/s]\n", + "100%|██████████| 3/3 [00:00<00:00, 17.92it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 3/3 [00:00<00:00, 10.35it/s]\n", + "100%|██████████| 3/3 [00:00<00:00, 22.56it/s]\n" + ] + } + ], + "source": [ + "# create your feature dataframe for each asset and concatenate\n", + "feature_df = pd.DataFrame()\n", + "for i in range(14):\n", + " print(i)\n", + " feature_df = pd.concat([feature_df,get_features(df_train,i,train=True)])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Merge Assets Features" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "block:merge_assets_features", + "prev:load_data", + "prev:feature_engineering" + ] + }, + "outputs": [], + "source": [ + "# assign weight column feature dataframe\n", + "feature_df = pd.merge(feature_df, df_asset_details[['Asset_ID','Weight']], how='left', on=['Asset_ID'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "feature_df.columns" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Modelling" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "block:modelling", + "prev:merge_assets_features" + ] + }, + "outputs": [], + "source": [ + "# define features for LGBM\n", + "features = ['Asset_ID', 'RSI_30', 'ATR_30',\n", + " 'DEMA_30', 'RSI_120', 'ATR_120', 'DEMA_120', 'RSI_240', 'ATR_240',\n", + " 'DEMA_240', 'sma_30', 'return_30', 'sma_120', 'return_120', 'sma_240',\n", + " 'return_240', 'HL', 'OC', 'lower_shadow', 'upper_shadow', 'Day',\n", + " 'dayofyear', 'weekofyear', 'season']\n", + "categoricals = ['Asset_ID']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# define train and validation weights and datasets\n", + "weights_train = feature_df.query('train_flg == 1')[['Weight']]\n", + "weights_test = feature_df.query('train_flg == 0')[['Weight']]\n", + "\n", + "train_dataset = lgb.Dataset(feature_df.query('train_flg == 1')[features], \n", + " feature_df.query('train_flg == 1')['Target'].values, \n", + " feature_name = features,\n", + " categorical_feature= categoricals)\n", + "val_dataset = lgb.Dataset(feature_df.query('train_flg == 0')[features], \n", + " feature_df.query('train_flg == 0')['Target'].values, \n", + " feature_name = features,\n", + " categorical_feature= categoricals)\n", + "\n", + "train_dataset.add_w = weights_train\n", + "val_dataset.add_w = weights_test\n", + "\n", + "evals_result = {}\n", + "params = {'n_estimators': int(N_EST),\n", + " 'objective': 'regression',\n", + " 'metric': 'rmse',\n", + " 'boosting_type': 'gbdt',\n", + " 'max_depth': -1, \n", + " 'learning_rate': float(LR),\n", + " 'seed': 2022,\n", + " 'verbose': -1,\n", + " }\n", + "\n", + "# train LGBM2\n", + "model = lgb.train(params = params,\n", + " train_set = train_dataset, \n", + " valid_sets = [val_dataset],\n", + " early_stopping_rounds=60,\n", + " verbose_eval = 30,\n", + " feval=weighted_correlation,\n", + " evals_result = evals_result \n", + " )\n", + "\n", + "joblib.dump(model, 'lgb.jl')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "fea_imp = pd.DataFrame({'imp':model.feature_importance(), 'col': features})\n", + "fea_imp = fea_imp.sort_values(['imp', 'col'], ascending=[True, False]).iloc[-30:]\n", + "_ = fea_imp.plot(kind='barh', x='col', y='imp', figsize=(20, 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Evaluation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "block:evaluation_result", + "prev:modelling" + ] + }, + "outputs": [], + "source": [ + "model = joblib.load('lgb.jl')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "root_mean_squared_error = model.best_score.get('valid_0').get('rmse')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "weighted_correlation = model.best_score.get('valid_0').get('eval_wcorr')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "pipeline-metrics" + ] + }, + "outputs": [], + "source": [ + "print(root_mean_squared_error)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "pipeline-metrics" + ] + }, + "outputs": [], + "source": [ + "print(weighted_correlation)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "kubeflow_notebook": { + "autosnapshot": true, + "experiment": { + "id": "2efb8e27-3b2e-439b-a53c-b1f9d7b94cfc", + "name": "g-research-crypto-forecasting" + }, + "experiment_name": "g-research-crypto-forecasting", + "katib_metadata": { + "algorithm": { + "algorithmName": "grid" + }, + "maxFailedTrialCount": 3, + "maxTrialCount": 12, + "objective": { + "objectiveMetricName": "", + "type": "minimize" + }, + "parallelTrialCount": 3, + "parameters": [] + }, + "katib_run": false, + "pipeline_description": "forecasting short term returns in 14 popular cryptocurrencies.", + "pipeline_name": "g-research-crypto-forecasting-pipeline", + "snapshot_volumes": true, + "steps_defaults": [ + "label:access-ml-pipeline:true", + "label:kaggle-secret:true", + "label:access-rok:true" + ], + "volume_access_mode": "rwm", + "volumes": [ + { + "annotations": [], + "mount_point": "/home/jovyan", + "name": "test-workspace-6lhtr", + "size": 15, + "size_type": "Gi", + "snapshot": false, + "type": "clone" + } + ] + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Natural-Language-Processing/2. Docker/static/styles.css b/Natural-Language-Processing/2. Docker/static/styles.css index 57efc4601..06916f65b 100644 --- a/Natural-Language-Processing/2. Docker/static/styles.css +++ b/Natural-Language-Processing/2. Docker/static/styles.css @@ -1,90 +1,90 @@ -body { - background-color: azure; - text-align: center; - font-family: fantasy; -} - -#title { - font-size: 10vh; -} - -#center { - margin-left: 10%; - margin-right: 10%; - width: 80vw; - height: 80vh; - opacity: 2.0; - background-color: blanchedalmond; - border: 5px solid #666; - border-radius: 50px; - box-shadow:-9px 12px 9px black -} - -#input { - float: left; - width: 50%; - height: 100%; -} - -#output { - float: right; - width: 50%; - height: 100%; -} - -.content-title { - font-size: 5vh; - margin: 2%; -} - -textarea { - margin: 5%; - width: 90%; - font-size: 4vh; -} - -input { - width: 30%; - height: 10%; - font-size: 4vh; - font-family: fantasy; - background-color: lawngreen; - border-radius: 50px; -} - -.content-setting { - font-size: 4vh; - text-align: left; - margin-left: 5%; -} - -#preprocess { - border: 5px solid grey; - border-radius: 10px; - width: 87%; - height: 25%; - margin: 5%; - background-color: white; - font-size: 4vh; - overflow: auto; - word-break: break-all; - word-wrap: break-word; - text-align: left; - font-family: monospace; -} - -table { - border: 5px solid grey; - border-radius: 10px; - font-size: 4vh; - margin: 5%; - width: 90%; - height: 25%; - background-color: white; -} - -.predict-title { - width: 33.33%; - height: 20%; - color: green; +body { + background-color: azure; + text-align: center; + font-family: fantasy; +} + +#title { + font-size: 10vh; +} + +#center { + margin-left: 10%; + margin-right: 10%; + width: 80vw; + height: 80vh; + opacity: 2.0; + background-color: blanchedalmond; + border: 5px solid #666; + border-radius: 50px; + box-shadow:-9px 12px 9px black +} + +#input { + float: left; + width: 50%; + height: 100%; +} + +#output { + float: right; + width: 50%; + height: 100%; +} + +.content-title { + font-size: 5vh; + margin: 2%; +} + +textarea { + margin: 5%; + width: 90%; + font-size: 4vh; +} + +input { + width: 30%; + height: 10%; + font-size: 4vh; + font-family: fantasy; + background-color: lawngreen; + border-radius: 50px; +} + +.content-setting { + font-size: 4vh; + text-align: left; + margin-left: 5%; +} + +#preprocess { + border: 5px solid grey; + border-radius: 10px; + width: 87%; + height: 25%; + margin: 5%; + background-color: white; + font-size: 4vh; + overflow: auto; + word-break: break-all; + word-wrap: break-word; + text-align: left; + font-family: monospace; +} + +table { + border: 5px solid grey; + border-radius: 10px; + font-size: 4vh; + margin: 5%; + width: 90%; + height: 25%; + background-color: white; +} + +.predict-title { + width: 33.33%; + height: 20%; + color: green; } \ No newline at end of file diff --git a/Natural-Language-Processing/2. Docker/templates/home.html b/Natural-Language-Processing/2. Docker/templates/home.html index 9f591e96e..77bd20469 100644 --- a/Natural-Language-Processing/2. Docker/templates/home.html +++ b/Natural-Language-Processing/2. Docker/templates/home.html @@ -1,156 +1,156 @@ - - - - Kubeflow - NLP - - -
Kubeflow - NLP
-
-
-
Message
-
- - -
-
-
-
Result
-
Positive +
-
Negative -
-
- {% print(data) %} -
- - - - - - - - - - - - - -
NumpySKlearnPytorchSVM
- {% if my_prediction_np == 1%} -
+
- {% elif my_prediction_np == 0%} -
-
- {% endif %} -
- {% if my_prediction_skl == 1%} -
+
- {% elif my_prediction_skl == 0%} -
-
- {% endif %} -
- {% if my_prediction_toc == 1%} -
+
- {% elif my_prediction_toc == 0%} -
-
- {% endif %} -
- {% if my_prediction_svm == 1%} -
+
- {% elif my_prediction_svm == 0%} -
-
- {% endif %} -
-
-
- - - + + + + Kubeflow - NLP + + +
Kubeflow - NLP
+
+
+
Message
+
+ + +
+
+
+
Result
+
Positive +
+
Negative -
+
+ {% print(data) %} +
+ + + + + + + + + + + + + +
NumpySKlearnPytorchSVM
+ {% if my_prediction_np == 1%} +
+
+ {% elif my_prediction_np == 0%} +
-
+ {% endif %} +
+ {% if my_prediction_skl == 1%} +
+
+ {% elif my_prediction_skl == 0%} +
-
+ {% endif %} +
+ {% if my_prediction_toc == 1%} +
+
+ {% elif my_prediction_toc == 0%} +
-
+ {% endif %} +
+ {% if my_prediction_svm == 1%} +
+
+ {% elif my_prediction_svm == 0%} +
-
+ {% endif %} +
+
+
+ + + diff --git a/RAG-pipeline-with-nodered/RAG_with_node-red/FL_pipeline.png b/RAG-pipeline-with-nodered/RAG_with_node-red/FL_pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..daab79b4361e37eeec19dbdd0b07e41ae9116a3a GIT binary patch literal 12001 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 literal 0 HcmV?d00001 diff --git a/RAG-pipeline-with-nodered/RAG_with_node-red/build_flow.png b/RAG-pipeline-with-nodered/RAG_with_node-red/build_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..5708f30c45a86c2c0a6298eba2d89b6f9c4945c4 GIT binary patch literal 5953 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 literal 0 HcmV?d00001 diff --git a/RAG-pipeline-with-nodered/RAG_with_node-red/edit_node.png b/RAG-pipeline-with-nodered/RAG_with_node-red/edit_node.png new file mode 100644 index 0000000000000000000000000000000000000000..9d0b6dee354bbdf5e047b06c811ab924c8159e74 GIT binary patch literal 7638 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 literal 0 HcmV?d00001 diff --git a/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/buckets/.usage.json/xl.meta b/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/buckets/.usage.json/xl.meta new file mode 100644 index 0000000000000000000000000000000000000000..04dcc8be1aff3019e1ed697574929027ac50e978 GIT binary patch literal 634 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 PN@b}<#Xy^stPE=bRMMOS literal 0 HcmV?d00001 diff --git a/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/format.json b/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/format.json new file mode 100644 index 000000000..134a49fc9 --- /dev/null +++ b/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/format.json @@ -0,0 +1 @@ +{"version":"1","format":"xl-single","id":"fd84d37c-ca41-455e-91a5-092551ea2351","xl":{"version":"3","this":"b6e74063-d6f7-410f-ad3f-4e8fe53877e1","sets":[["b6e74063-d6f7-410f-ad3f-4e8fe53877e1"]],"distributionAlgo":"SIPMOD+PARITY"}} \ No newline at end of file diff --git a/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/pool.bin/xl.meta b/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/pool.bin/xl.meta new file mode 100644 index 0000000000000000000000000000000000000000..03d9f27858165b9808078c96808f121a4ea54b31 GIT binary patch literal 479 zcma#>F;ZY;U}iYRz`$6<%*1#^ZTb-b1~hP4{MHX;^~I}K9bw77qa4J@#=v-#(WQAw zNM%7P#Y41$Y1T`;vSadF8kIwEjQW8&RRPnS14Ub?K@R_^Gw%r)6DCq18W zv1_s~i11@r?wafroLQB6i2-OmkmH$`l3KwCROgaeTr!byg>!IeE?CQofW)E_ztY^| ziHs{jOxKXa^x^|xCP;trM59$8VMi!u35YgY>Kl@on+o^Ga^KXF#Nf)}#yu6fxtV#H z`MQ~TC8w#RWOV6I&K#rZ6l@&RMDta_gd;(&Id=pm<9wwce|K=5NO0 Il+@${07;9oHUIzs literal 0 HcmV?d00001 diff --git a/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/7a4afe59-3ebb-451e-8f3e-2aa2972ace33/xl.meta.bkp b/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/7a4afe59-3ebb-451e-8f3e-2aa2972ace33/xl.meta.bkp new file mode 100644 index 0000000000000000000000000000000000000000..232e8ac25b6547254e2b01139b2db98591364012 GIT binary patch literal 634 zcma#>F;ZY;U}iYRz`$6*%*1#^ZTb-b1~hP4{MK*dSNlqTA7Od!yg-JLje+qfqf_&e zkjjEo#-(9K{z+N)7z7u2x?pNu;^LB7bVNXRwqLaTFIS!Us%~sY*X^FZ%r)6DCq18W zv1_s~i11@r?wafroLQB6i2-OmkmH$`l3KwCROgaeTr!byg>!IeE?CQofW)E_ztY^| ziHs{jOxKXa^x^|xCP;tr#ET5)SAirP;oK!47EpMpZ%AftD%>~AeN#&kgDZ<0_f+WS zX69w)>t^Paq!#5R<^UNvnR%(YDTyVCM_5XVN>jmVLyL==mH_pn-&8O$PBBh0vNTRK zu}C&aGO;uu4p``>|!Xz*tjIGG$-fC`$OT!x3NEV`FwMm%l==zfjVrBS90eVeCq6(bM?yh zdcF_UN;!$eC7}gCN2MxRDH#|T80vyih=G9>7)2@RDCH+*r6!jYJLi|?l_*&m=qQz? z78L{SMG{F#%}Fgu^-V0w21+3mLUo4Zmn7zZ0t~DhDj1Xs_kd?!TE3DM$jLfNNu|lz WsmPW=1wxAx(^Ii11jh(Ob1eW!{OHL5 literal 0 HcmV?d00001 diff --git a/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/9fb77816-7f6e-40e0-8b08-f7ca83d930d1/xl.meta.bkp b/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/9fb77816-7f6e-40e0-8b08-f7ca83d930d1/xl.meta.bkp new file mode 100644 index 0000000000000000000000000000000000000000..0cd103e26e513e64aa70101d935d89b0de5812a2 GIT binary patch literal 741 zcma#>F;ZY;U}iYRz`$6+%*1#^ZTb-b1~hP4{MK*dS39P!Kf-b>huMLVje+qfqgV5i zkjjEo#-(9K{z+N)7z7u2x?pNu;^LB7bVMN9A>K}Jy?0LM(!YiwKBtqHxh6a2q~|j( zc1`vL5q=EIU6Y-HGpkZBF#xRxay;`=QY#pN>Rd95OC~a|a1Jib1#4LmkXTgWSDITq zk#Qx6=^B!lUVH$|1nDoHc#+X?6-dGn&Rqgx0fm?PhGgcZ!hN&cH?<@&xU#r$Plax7 zW?p8#Zf0IdYEfQd4v>+PnU|`Yl30>>gr%gYG!?8iw795g2~bb^O@)*+1M`#=BQp~V zqofoQQ;Ve3RHM|S#6%NwQ*(0*1IsnZ`9QPsN_0zrVYDN$pdcqRIk6-&KTkhDxg@nj zx45JzH8FQ#*}1gripF!^tN&OrHZI94&B-~+7$~>8!#!%ksTEYlxQq3E&+NwHRU)DD@a9JsmBZMIX3Ut zC08crq&ny47UZM?W$!Quz!f;LD~m`9!?~`ZMoSjGM{p+^t(M%3;GQ+w$lwg;x^WsU zKT(X}PT)>kvj)LE!<~L|7o6+P!Cl&1f#AAuXO?_Ja2vQQ7q3Kc_i%S#IEvu@;GWBO i5YF{5;hyh$8^JB$ULgAe!Ck{WXVqH-_XYQS-}wNgQ~T2Z literal 0 HcmV?d00001 diff --git a/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/a4349609-22f1-4a1f-b126-76ba138ed9ed/xl.meta.bkp b/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/a4349609-22f1-4a1f-b126-76ba138ed9ed/xl.meta.bkp new file mode 100644 index 0000000000000000000000000000000000000000..7e89dcadadf9d50b4c992aaf5249c7271d01894c GIT binary patch literal 634 zcma#>F;ZY;U}iYRz`$6*%*1#^ZTb-b1~hP4{MPRT=94a}M_9`5%1vfuV_-bW=+wL< zq_QBDacP*5e^S;x2Ej$1E|^-ExVU5%9T8Y1IeE^K3mzuR*Z=+CXKYxy%r)6DCq18W zv1_s~i11@r?wafroLQB6i2-OmkmH$`l3KwCROgaeTr!byg>!IeE?CQofW)E_ztY^| ziHs{jOxKXa^x^|xCP;tr#ET5)SAirP;oK!47EpMpZ%AftD%>~AeN#&kgDZ<0_f+WS zX69w)>t^Paq!#5R<^UNvnR%(YDTyVCM_5XVN>jmVLyL==)+FZx73G!amH<7!A+ew! zCo?&*Br`uxKdU%DZwb)E^qUGM#wo^0MwZ5jCKkyiNhX#iMybYz7RF|&#wG>^$tlST z%g&``S2Uh`UutlRv2jUWX->|O_lLrdZ)1P#^7-aAm;Jwb19jLMujI}#_|(}m=jxU1 z^?VF;ZY;U}iYRz`$6*%*1#^ZTb-b1~hP4{MPRv?%Ly5j<8H>eCWu?#=v-#(W!Y! zNM%7P#Y41$Y1T`;vSadF8kIwH_>B>cPm0w48tKl87q`c7N3%r)6DCq18W zv1_s~i11@r?wafroLQB6i2-OmkmH$`l3KwCROgaeTr!byg>!IeE?CQofW)E_ztY^| ziHs{jOxKXa^x^|xCP;tr#ET5)SAirP;oK!47EpMpZ%AftD%>~AeN#&kgDZ<0_f+WS zX69w)>t^Paq!#5R<^UNvnR%(YDTyVCM_5XVN>jmVLyL==mH_pn-&8O$PBBh0vNTRK zu}C&aGO;uu4p``q@-iU*tjIGG$-fC`$OT!x3NEV`FwMm%l==zfjVrBS90eVeCq6(bM?yh zdcF_UN;!$eC7}gCN2MxRDH#|T80vyih=G9>7)2@RDCH+*r6!jYJLi|?l_*&m=qQz? z78L{SMG{F#%}Fgu^-V0w21+3mLUo4Zmn7zZ0t~DhDj1Xs_kd?!TE3DM$jLfNNu|lz WsmPW=1wxAx(^Ii11jh(Ob1eYccIjUL literal 0 HcmV?d00001 diff --git a/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/eb32cdeb-d251-4717-bcd7-d215b85af238/xl.meta.bkp b/RAG-pipeline-with-nodered/RAG_with_node-red/example/data/.minio.sys/tmp/.trash/eb32cdeb-d251-4717-bcd7-d215b85af238/xl.meta.bkp new file mode 100644 index 0000000000000000000000000000000000000000..57a5da24a5c9b8b941f937c5326beaccd79712ef GIT binary patch literal 741 zcma#>F;ZY;U}iYRz`$6+%*1#^ZTb-b1~hP4{MPRv?(!QOj<7gB@Ls{l#=v-#(W`k$ zNM%7P#Y41$Y1T`;vSadF8kIwBx+f^R~MpYMSkwv7hcviJp;xh6a2q~|j( zc1`vL5q=EIU6Y-HGpkZBF#xRxay;`=QY#pN>Rd95OC~a|a1Jib1#4LmkXTgWSDITq zk#Qx6=^B!lUVH$|1nDoHc#+X?6-dGn&Rqgx0fm?PhGgcZ!hN&cH?<@&xU#r$Plax7 zW?p8#Zf0IdYEfQd4v>+PnU|`Yl30>>gr%gYG!?8iw795g2~bb^O@+jyL<^%t3-hG3 zq@)zH#H3UcgQR3jb5jEo(^O-#=Qr#qNaOl=rqKQN@eIv< z1$owb+wNZae7??E6B<1&%acosih!0dEXhl)DA8PATmtlVYRYjQR*;IcQqN4~D5dl3 zk}H#QQl0a23vyC{vUeB+;0jzrjg~BWkKj%;S}nO5!98oVk--_xb>lQzexew`oxq*8 zW(|UShCBV_E;!engS)i30>O3R&Mf(c;5KkqE?$Y??&0pfa1_D)!9ADnAe`%A!ad*h iHiBEgy+HN{g1d%$&Z@Tv?hEeuzVqQ+UF;ZY;U}iYRz`$6+%*1#^ZTb-b1~hP4{MPRT=Hq+bA7Qz*=Rq7J8w2A}Mz7{2 zA(aKGj7!6e{FAcoF$ga5bivfR#Kk4E=!ih#b<-n1WqpI18&gV8J=6DI=9=u7lb+AG z*frS~MEEf*cTIK*&a6tk!~nD&$nnfeNv&W6s&mOKE}6))WqC{W#`heD;m%J+AhA9v2jUWX->{j#z1C=+wzTzl~#Jct2ia9-_dKiZTkb> z#E307Om*kf<{lv^5oK@BA_JT`{C z$(6}Dsm}Si1v#le**gpZa0RXtjaEx;MsUv>ZDeqUbKN+NmY*m_a3^r5tyzQMp5abE zxeLy9=in}Fu0U{IxHC(>A-E0Pm5Wy*xO=#}FC0a1e{j#`I|%1`m~hW`y^Y`&a4(Sk if#9y;p0nyLg8PDdzVCcE*E3T&UN#NEU8

y3=dn&&`eS#o75B=1`amwagrcqUA#?ah+aj1R-^#-R%~LDkYU+yinX=K=6MTR z_;+Us_J^l2M~f;({oWRNwk0LzV3T#K9fym+ZDmB7`Jh(q&cz*d@>jF$a&yu%^d=1M z0?YiYfm#EaY^_axL*S>LPx_IdmB4)rrD7?*)(btqpj@_jTje^dYk#)+ z0DX}pYwCFPlKC48d^SXgux4!HBuD=OeV>`>=E=KB`0_n4Fay@$iTFtLV6gD(LP}vI zx?ei^!^U{Dl!mck|C#8ZT6|(+;<RgP+bjv*@e~o=*%GUBl_FfnP9?O5{2y-+^OC zdw1T0InO5mZv2zlTi`PKf&L~v{i_8CUTO4ZrLihau6lt@8Bz}yB-(xEhri&>EuD^?QWoFStfgaQGxr?z&5eI!Dkh3BWAcqdynC)N1AV|j=)nm<+Ec1 zmJ$lJz7uC#6)hwWC54}g@!!y^i{Z)19RojYp9e;vEr zwiWDPOJY8v*rc4Oz28iz!s%&A>jdFpE3*zk& zwR=WI`nQ_Ad_>1)R#;9_xu)6a=;goRcHF2NS?-eJ;^KZH^i3Oxav=(tpc&KdZhM8{ zM0sF9G&D4fV|&dtpet&+x1ex`%ZPLO~q~GF`D06b}=#Owo_(%ryjgECn#z3FvKf_<~Z=rkgtYWm`GtNv6jO;$gSYyA9sR%=bw zFj2mXMPu+}{1qxfj4NSfmG?;H0AFu4itt1f!~i*`vTIa6tRz z5a3s&oouJ3O0Q-iZKtRcatuG-nJyT%oZfH-N<1T@jJzCI!@y^ls0W~PcA}W0aB^cT z<`_OruU9$<8$RAK808;y4>*S3I@m!8cf3>_lySQtdgpCj2t8Psi%fcLlv_~`!7ENd z9*=Tuz-RlWyoAaB?t9VDq`Va{i>3(cHSnrR^#s}8_;(ikVjwsg8+KfOSrN0U&YTwZ983?RqQ;j zXUDe$M~SLe8oVofq{X6|+C+7vO+W3HDuDvbD#ZRhN1syU9E0=w*^OaIzYJ)-JPj9rVgAo-D!@E{|Z`_L_Rik6Xg-NJ!tPP zlyqJbG^pHlC|IJ9@lE8E2)omgo0)06*cSFNxKFR|=IDZ3!?lz=plH-88VL;z1rtg{ zaj~d{J=j_zzl7~A&R;ud-Z$1hsfQ6%Fx~@@^VxA>N5W|a+loe`2OLHt*azO*yxv;Ntteji@VjQmR{TCbk5E|VDksaab3^H;}j6A}-k1AZUi8%pp$r80kmY-)-7bu;=-$EO&W&uRmZ z95{#?HsKksp7-De2*jwy?CyweCdhYWLgVB?ND1^nE`Hf==Bz~K^1P9j-{UygL>$8b zV1bcO7D=<<4O(x_e>`3H)q8ZId->L@ZzhotxL3u!q>Q){GUv|Q%O*}Oo|FF`d;NUQ zA-irlVc#_~NTwp);IiQYySCq+#V3J5CR|NJBiR1ctFau>i}ebgb!<~$S_PIV!p7Al zGyz%A0|N+dk;W#N#R;IC_($4|HVl5gsRi>G~f(je$|)rcWHRTvmU-CR~9JI&5?7&&zuHNrt z1%fAh+AnDE`U3@R?IZzU%4+x=8|(kBgNk5&+Kle?mDBgi!wZnM1jsYr%LCC%;8$#I z2R*Y$aV$V^l%kRvPbt$k$4rckjlDuVzYN~?1p|2Hf;nFGPftJcCt>^101mH;@syUa z@qL%;_()*U3=+N(B>Mz|?m8Mcvo&-gT(Ves_oQ8i(HlVHzSQReF*@%QLUa?@+BFJa z5fBoh)u>zYNopP5DfK~aR|!LAaFE5?RXacwg@c0=q@kt;0{I{1KcJ!GVpxscd>14tL&Bn$ z`Ho<(g93WmrffWslV_*WjY~^QV-EQEEI`ox0f1kB;GC+79-HTTvuP7dQjBy$JX?a= zaD`E62C5Dw^RibhkGx>3yK(Mkv}%70y7yjnz?t(vd|9Lt@@i&NgE|N<4 r4+aoiOji!}-_z`$mzKZzd5J#wT6E4fva0VIc)gHPkSrE|^Wpyh<;A;+ literal 0 HcmV?d00001 diff --git a/RAG-pipeline-with-nodered/node-red_2.png b/RAG-pipeline-with-nodered/node-red_2.png new file mode 100644 index 0000000000000000000000000000000000000000..6a69afef552ea2d80e1cfd89c81fa69f9daea39d GIT binary patch literal 33070 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 literal 0 HcmV?d00001 diff --git a/RAG-pipeline-with-nodered/pipeline.png b/RAG-pipeline-with-nodered/pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..0dfe54a585fae326b76fea383bfd5d6159769ed7 GIT binary patch literal 12988 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 American Express is a globally integrated payments company. The largest payment card issuer in the world, they provide customers with access to products, insights, and experiences that enrich lives and build business success.\n", - "\n", - "The dataset provided is an industrial scale data set of about 5.5 million rows. It has been pre-processed and converted to a lightweight version by raddar for ease of training and better result. This dataset is available in a [parquet format][1].\n", - "\n", - "[1]: https://www.kaggle.com/datasets/raddar/amex-data-integer-dtypes-parquet-format" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Install necessary packages\n", - "\n", - "We can install the necessary package by either running pip install --user or include everything in a requirements.txt file and run pip install --user -r requirements.txt. We have put the dependencies in a requirements.txt file so we will use the former method.\n", - "\n", - "NOTE: After installing python packages, restart notebook kernel before proceeding." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "!pip install -r requirements.txt --user --quiet" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Imports\n", - "\n", - "In this section we import the packages we need for this example. Make it a habit to gather your imports in a single place. It will make your life easier if you are going to transform this notebook into a Kubeflow pipeline using Kale." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "tags": [ - "imports" - ] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import os, subprocess\n", - "import random, zipfile, joblib\n", - "import scipy.stats\n", - "import warnings\n", - "import gc, wget\n", - "\n", - "from sklearn.model_selection import StratifiedKFold\n", - "from lightgbm import LGBMClassifier\n", - "\n", - "warnings.filterwarnings(\"ignore\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Project hyper-parameters\n", - "\n", - "In this cell, we define the different hyper-parameters. Defining them in one place makes it easier to experiment with their values and also facilitates the execution of HP Tuning experiments using Kale and Katib." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "tags": [ - "pipeline-parameters" - ] - }, - "outputs": [], - "source": [ - "# Hyper-parameters\n", - "N_EST = 30\n", - "LR = 0.1" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "Set random seed for reproducibility" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "def fix_all_seeds(seed):\n", - " np.random.seed(seed)\n", - " random.seed(seed)\n", - " os.environ['PYTHONHASHSEED'] = str(seed)\n", - "\n", - "fix_all_seeds(2022)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Download data\n", - "\n", - "In this section, we download the data from kaggle using the Kaggle API credentials" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "block:download_data" - ] - }, - "outputs": [], - "source": [ - "# setup kaggle environment for data download\n", - "dataset = \"amex-data-integer-dtypes-parquet-format\"\n", - "\n", - "# setup kaggle environment for data download\n", - "with open('/secret/kaggle-secret/password', 'r') as file:\n", - " kaggle_key = file.read().rstrip()\n", - "with open('/secret/kaggle-secret/username', 'r') as file:\n", - " kaggle_user = file.read().rstrip()\n", - "\n", - "os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", - "\n", - "# download kaggle's Amex-credit-prediction data\n", - "subprocess.run([\"kaggle\",\"datasets\", \"download\", \"-d\", f'raddar/{dataset}'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "block:" - ] - }, - "outputs": [], - "source": [ - "# path to download to\n", - "data_path = 'data'\n", - "\n", - "# extract Amex-credit-prediction.zip to data_path\n", - "with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", - " zip_ref.extractall(data_path)\n", - " \n", - "# download kaggle's Amex-credit-prediction train_labels.zip\n", - "download_link = \"https://github.com/kubeflow/examples/blob/master/american-express-default-kaggle-competition/data/train_labels.zip?raw=true\"\n", - "wget.download(download_link, f'{data_path}/train_labels.zip')\n", - "\n", - "# extract Amex-credit-prediction.zip to data_path\n", - "with zipfile.ZipFile(f'{data_path}/train_labels.zip','r') as zip_ref:\n", - " zip_ref.extractall(data_path)\n", - " \n", - "# delete zipfiles\n", - "subprocess.run(['rm', f'{dataset}.zip'])\n", - "subprocess.run(['rm', f'{data_path}/train_labels.zip'])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Load the dataset\n", - "\n", - "First, let us load and analyze the data.\n", - "\n", - "The data is in csv format, thus, we use the handy read_csv pandas method." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "tags": [ - "block:load_data", - "prev:download_data" - ] - }, - "outputs": [], - "source": [ - "TRAIN_CSV = (f'{data_path}/train.parquet')\n", - "TEST_CSV = f'{data_path}/test.parquet'\n", - "TARGET_CSV = f'{data_path}/train_labels.csv'" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "target shape: (458913,)\n" - ] - } - ], - "source": [ - "df_train = pd.read_parquet(TRAIN_CSV)\n", - "df_test = pd.read_parquet(TEST_CSV)\n", - "target = pd.read_csv(TARGET_CSV).target.values\n", - "print(f\"target shape: {target.shape}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(5531451, 190)" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "customer_ID 0\n", - "S_2 0\n", - "P_2 45985\n", - "D_39 0\n", - "B_1 0\n", - " ... \n", - "D_141 101548\n", - "D_142 4587043\n", - "D_143 0\n", - "D_144 40727\n", - "D_145 0\n", - "Length: 190, dtype: int64" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train.isna().sum()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "### Define Helper Functions" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "tags": [ - "functions" - ] - }, - "outputs": [], - "source": [ - "# @yunchonggan's fast metric implementation\n", - "# From https://www.kaggle.com/competitions/amex-default-prediction/discussion/328020\n", - "def amex_metric(y_true: np.array, y_pred: np.array) -> float:\n", - "\n", - " # count of positives and negatives\n", - " n_pos = y_true.sum()\n", - " n_neg = y_true.shape[0] - n_pos\n", - "\n", - " # sorting by descring prediction values\n", - " indices = np.argsort(y_pred)[::-1]\n", - " preds, target = y_pred[indices], y_true[indices]\n", - "\n", - " # filter the top 4% by cumulative row weights\n", - " weight = 20.0 - target * 19.0\n", - " cum_norm_weight = (weight / weight.sum()).cumsum()\n", - " four_pct_filter = cum_norm_weight <= 0.04\n", - "\n", - " # default rate captured at 4%\n", - " d = target[four_pct_filter].sum() / n_pos\n", - "\n", - " # weighted gini coefficient\n", - " lorentz = (target / n_pos).cumsum()\n", - " gini = ((lorentz - cum_norm_weight) * weight).sum()\n", - "\n", - " # max weighted gini coefficient\n", - " gini_max = 10 * n_neg * (1 - 19 / (n_pos + 20 * n_neg))\n", - "\n", - " # normalized weighted gini coefficient\n", - " g = gini / gini_max\n", - "\n", - " return 0.5 * (g + d)\n", - "\n", - "def lgb_amex_metric(y_true, y_pred):\n", - " \"\"\"The competition metric with lightgbm's calling convention\"\"\"\n", - " return ('amex_metric_score',\n", - " amex_metric(y_true, y_pred),\n", - " True)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Feature Engineering" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "tags": [ - "block:feature_engineering", - "prev:load_data" - ] - }, - "outputs": [], - "source": [ - "# feature engineering gotten from https://www.kaggle.com/code/ambrosm/amex-lightgbm-quickstart\n", - "def get_features(df, \n", - " features_avg, \n", - " features_min, \n", - " features_max, \n", - " features_last\n", - " ):\n", - " '''\n", - " This function takes a dataframe with all features and returns the aggregated feature grouped by the customer id.\n", - " \n", - " df - dataframe\n", - " '''\n", - " cid = pd.Categorical(df.pop('customer_ID'), ordered=True) # get customer id\n", - " last = (cid != np.roll(cid, -1)) # mask for last statement of every customer\n", - " \n", - " df_avg = (df\n", - " .groupby(cid)\n", - " .mean()[features_avg]\n", - " .rename(columns={f: f\"{f}_avg\" for f in features_avg})\n", - " ) \n", - " \n", - " df_min = (df\n", - " .groupby(cid)\n", - " .min()[features_min]\n", - " .rename(columns={f: f\"{f}_min\" for f in features_min})\n", - " )\n", - " gc.collect()\n", - " print('Computed min')\n", - " \n", - " df_max = (df\n", - " .groupby(cid)\n", - " .max()[features_max]\n", - " .rename(columns={f: f\"{f}_max\" for f in features_max})\n", - " )\n", - " gc.collect()\n", - " print('Computed max')\n", - " \n", - " df = (df.loc[last, features_last]\n", - " .rename(columns={f: f\"{f}_last\" for f in features_last})\n", - " .set_index(np.asarray(cid[last]))\n", - " )\n", - " gc.collect()\n", - " print('Computed last')\n", - " \n", - " df_ = pd.concat([df, df_min, df_max, df_avg], axis=1, )\n", - " \n", - " del df, df_avg, df_min, df_max, cid, last\n", - " \n", - " return df_" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "features_avg = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', \n", - " 'B_16', 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_28', 'B_29', 'B_30', \n", - " 'B_32', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', \n", - " 'D_45', 'D_46', 'D_47', 'D_48', 'D_50', 'D_51', 'D_53', 'D_54', 'D_55', 'D_58', 'D_59', 'D_60', 'D_61', \n", - " 'D_62', 'D_65', 'D_66', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_75', 'D_76', 'D_77', 'D_78', \n", - " 'D_80', 'D_82', 'D_84', 'D_86', 'D_91', 'D_92', 'D_94', 'D_96', 'D_103', 'D_104', 'D_108', 'D_112', 'D_113', \n", - " 'D_114', 'D_115', 'D_117', 'D_118', 'D_119', 'D_120', 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', \n", - " 'D_128', 'D_129', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', 'D_140', 'D_141', 'D_142', 'D_144', \n", - " 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_2', 'R_3', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_14', 'R_15', 'R_16', \n", - " 'R_17', 'R_20', 'R_21', 'R_22', 'R_24', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_9', 'S_11', 'S_12', 'S_13', \n", - " 'S_15', 'S_16', 'S_18', 'S_22', 'S_23', 'S_25', 'S_26']\n", - "features_min = ['B_2', 'B_4', 'B_5', 'B_9', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', 'B_19', 'B_20', 'B_28', 'B_29', 'B_33', 'B_36', \n", - " 'B_42', 'D_39', 'D_41', 'D_42', 'D_45', 'D_46', 'D_48', 'D_50', 'D_51', 'D_53', 'D_55', 'D_56', 'D_58', 'D_59', \n", - " 'D_60', 'D_62', 'D_70', 'D_71', 'D_74', 'D_75', 'D_78', 'D_83', 'D_102', 'D_112', 'D_113', 'D_115', 'D_118', 'D_119', \n", - " 'D_121', 'D_122', 'D_128', 'D_132', 'D_140', 'D_141', 'D_144', 'D_145', 'P_2', 'P_3', 'R_1', 'R_27', 'S_3', 'S_5', \n", - " 'S_7', 'S_9', 'S_11', 'S_12', 'S_23', 'S_25']\n", - "features_max = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', \n", - " 'B_18', 'B_19', 'B_21', 'B_23', 'B_24', 'B_25', 'B_29', 'B_30', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_42', 'D_39', \n", - " 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', 'D_48', 'D_49', 'D_50', 'D_52', 'D_55', 'D_56', 'D_58', 'D_59', \n", - " 'D_60', 'D_61', 'D_63', 'D_64', 'D_65', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_76', 'D_77', 'D_78', 'D_80', 'D_82', \n", - " 'D_84', 'D_91', 'D_102', 'D_105', 'D_107', 'D_110', 'D_111', 'D_112', 'D_115', 'D_116', 'D_117', 'D_118', 'D_119', \n", - " 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', 'D_128', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', \n", - " 'D_138', 'D_140', 'D_141', 'D_142', 'D_144', 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_3', 'R_5', 'R_6', 'R_7', 'R_8', \n", - " 'R_10', 'R_11', 'R_14', 'R_17', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_7', 'S_8', 'S_11', 'S_12', 'S_13', 'S_15', 'S_16', \n", - " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']\n", - "features_last = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', \n", - " 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_26', 'B_28', 'B_29', 'B_30', 'B_32', 'B_33', \n", - " 'B_36', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', \n", - " 'D_48', 'D_49', 'D_50', 'D_51', 'D_52', 'D_53', 'D_54', 'D_55', 'D_56', 'D_58', 'D_59', 'D_60', 'D_61', 'D_62', 'D_63', \n", - " 'D_64', 'D_65', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_75', 'D_76', 'D_77', 'D_78', 'D_79', 'D_80', 'D_81', 'D_82', \n", - " 'D_83', 'D_86', 'D_91', 'D_96', 'D_105', 'D_106', 'D_112', 'D_114', 'D_119', 'D_120', 'D_121', 'D_122', 'D_124', 'D_125', \n", - " 'D_126', 'D_127', 'D_130', 'D_131', 'D_132', 'D_133', 'D_134', 'D_138', 'D_140', 'D_141', 'D_142', 'D_145', 'P_2', 'P_3', \n", - " 'P_4', 'R_1', 'R_2', 'R_3', 'R_4', 'R_5', 'R_6', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_12', 'R_13', 'R_14', 'R_15', \n", - " 'R_19', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_8', 'S_9', 'S_11', 'S_12', 'S_13', 'S_16', 'S_19', 'S_20', \n", - " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# apply feature engineering function\n", - "train = get_features(df_train, features_avg, features_min, features_max, features_last)\n", - "test = get_features(df_test, features_avg, features_min, features_max, features_last)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# check null values\n", - "train.isna().any()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Modelling: StratifiedKFold\n", - "\n", - "We cross-validate with a six-fold StratifiedKFold to handle the imbalanced nature of the target.\n", - "\n", - "Lightgbm handles null values efficiently." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "block:modelling", - "prev:feature_engineering" - ] - }, - "outputs": [], - "source": [ - "# Cross-validation\n", - "\n", - "features = [f for f in train.columns if f != 'customer_ID' and f != 'target']\n", - "\n", - "print(f\"{len(features)} features\")\n", - "\n", - "score_list = [] # lgbm score per fold\n", - "y_pred_list = [] # fold predictions list\n", - "\n", - "# init StratifiedKFold\n", - "kf = StratifiedKFold(n_splits=4)\n", - "\n", - "for fold, (idx_tr, idx_va) in enumerate(kf.split(train, target)):\n", - " \n", - " X_tr, X_va, y_tr, y_va, model = None, None, None, None, None\n", - "\n", - " X_tr = train.iloc[idx_tr][features]\n", - " X_va = train.iloc[idx_va][features]\n", - " y_tr = target[idx_tr]\n", - " y_va = target[idx_va]\n", - " \n", - " # init model\n", - " model = LGBMClassifier(n_estimators=int(N_EST),\n", - " learning_rate=float(LR), \n", - " random_state=2022)\n", - " # fit model\n", - " model.fit(X_tr, y_tr,\n", - " eval_set = [(X_va, y_va)], \n", - " eval_metric=[lgb_amex_metric],\n", - " verbose = 20,\n", - " early_stopping_rounds=30)\n", - " \n", - " X_tr, y_tr = None, None\n", - " \n", - " # fold validation set predictions\n", - " y_va_pred = model.predict_proba(X_va, raw_score=True)\n", - " \n", - " # model score\n", - " score = amex_metric(y_va, y_va_pred)\n", - "\n", - " print(f\"Score = {score}\")\n", - " score_list.append(score)\n", - " \n", - " # test set predictions\n", - " y_pred_list.append(model.predict_proba(test[features], raw_score=True))\n", - " \n", - " print(f\"Fold {fold}\") \n", - "\n", - "# save model\n", - "joblib.dump(model, 'lgb.jl')\n", - "print(f\"OOF Score: {np.mean(score_list):.5f}\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# feature importance for top 30 features\n", - "fea_imp = pd.DataFrame({'imp':model.feature_importances_, 'col': features})\n", - "fea_imp = fea_imp.sort_values(['imp', 'col'], ascending=[True, False]).iloc[-30:]\n", - "_ = fea_imp.plot(kind='barh', x='col', y='imp', figsize=(20, 10))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Evaluation" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "block:evaluation_result", - "prev:modelling" - ] - }, - "outputs": [], - "source": [ - "model = joblib.load('lgb.jl')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "binary_logloss = model.booster_.best_score.get('valid_0').get('binary_logloss')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "amex_metric_score = model.booster_.best_score.get('valid_0').get('amex_metric_score')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "pipeline-metrics" - ] - }, - "outputs": [], - "source": [ - "print(binary_logloss)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "pipeline-metrics" - ] - }, - "outputs": [], - "source": [ - "print(amex_metric_score)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Submission" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "sub = pd.DataFrame({'customer_ID': test.index,\n", - " 'prediction': np.mean(y_pred_list, axis=0)})\n", - "sub.to_csv('submission.csv', index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "sub" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kubeflow_notebook": { - "autosnapshot": true, - "experiment": { - "id": "new", - "name": "american-express-defaul-prediction" - }, - "experiment_name": "american-express-defaul-prediction", - "katib_metadata": { - "algorithm": { - "algorithmName": "grid" - }, - "maxFailedTrialCount": 3, - "maxTrialCount": 12, - "objective": { - "objectiveMetricName": "", - "type": "minimize" - }, - "parallelTrialCount": 3, - "parameters": [] - }, - "katib_run": false, - "pipeline_description": "predicting credit default", - "pipeline_name": "american-express-defaul-prediction-pipeline", - "snapshot_volumes": true, - "steps_defaults": [ - "label:access-ml-pipeline:true", - "label:kaggle-secret:true", - "label:access-rok:true" - ], - "volume_access_mode": "rwm", - "volumes": [ - { - "annotations": [], - "mount_point": "/home/jovyan", - "name": "test-workspace-qtvmt", - "size": 32, - "size_type": "Gi", - "snapshot": false, - "type": "clone" - } - ] - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.9" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# 🪙 American Express - Default Prediction Competition Kale Pipeline\n", + "![](./images/background.jpg)\n", + "\n", + "---\n", + "\n", + "In this [Kaggle competition](https://www.kaggle.com/competitions/g-research-crypto-forecasting/overview), you'll use your machine learning expertise to predict credit default. This competition is hosted by American Express. \n", + "\n", + "> American Express is a globally integrated payments company. The largest payment card issuer in the world, they provide customers with access to products, insights, and experiences that enrich lives and build business success.\n", + "\n", + "The dataset provided is an industrial scale data set of about 5.5 million rows. It has been pre-processed and converted to a lightweight version by raddar for ease of training and better result. This dataset is available in a [parquet format][1].\n", + "\n", + "[1]: https://www.kaggle.com/datasets/raddar/amex-data-integer-dtypes-parquet-format" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Install necessary packages\n", + "\n", + "We can install the necessary package by either running pip install --user or include everything in a requirements.txt file and run pip install --user -r requirements.txt. We have put the dependencies in a requirements.txt file so we will use the former method.\n", + "\n", + "NOTE: After installing python packages, restart notebook kernel before proceeding." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "!pip install -r requirements.txt --user --quiet" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Imports\n", + "\n", + "In this section we import the packages we need for this example. Make it a habit to gather your imports in a single place. It will make your life easier if you are going to transform this notebook into a Kubeflow pipeline using Kale." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "tags": [ + "imports" + ] + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import os, subprocess\n", + "import random, zipfile, joblib\n", + "import scipy.stats\n", + "import warnings\n", + "import gc, wget\n", + "\n", + "from sklearn.model_selection import StratifiedKFold\n", + "from lightgbm import LGBMClassifier\n", + "\n", + "warnings.filterwarnings(\"ignore\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Project hyper-parameters\n", + "\n", + "In this cell, we define the different hyper-parameters. Defining them in one place makes it easier to experiment with their values and also facilitates the execution of HP Tuning experiments using Kale and Katib." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "pipeline-parameters" + ] + }, + "outputs": [], + "source": [ + "# Hyper-parameters\n", + "N_EST = 30\n", + "LR = 0.1" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "Set random seed for reproducibility" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "def fix_all_seeds(seed):\n", + " np.random.seed(seed)\n", + " random.seed(seed)\n", + " os.environ['PYTHONHASHSEED'] = str(seed)\n", + "\n", + "fix_all_seeds(2022)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Download data\n", + "\n", + "In this section, we download the data from kaggle using the Kaggle API credentials" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "block:download_data" + ] + }, + "outputs": [], + "source": [ + "# setup kaggle environment for data download\n", + "dataset = \"amex-data-integer-dtypes-parquet-format\"\n", + "\n", + "# setup kaggle environment for data download\n", + "with open('/secret/kaggle-secret/password', 'r') as file:\n", + " kaggle_key = file.read().rstrip()\n", + "with open('/secret/kaggle-secret/username', 'r') as file:\n", + " kaggle_user = file.read().rstrip()\n", + "\n", + "os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", + "\n", + "# download kaggle's Amex-credit-prediction data\n", + "subprocess.run([\"kaggle\",\"datasets\", \"download\", \"-d\", f'raddar/{dataset}'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "block:" + ] + }, + "outputs": [], + "source": [ + "# path to download to\n", + "data_path = 'data'\n", + "\n", + "# extract Amex-credit-prediction.zip to data_path\n", + "with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", + " zip_ref.extractall(data_path)\n", + " \n", + "# download kaggle's Amex-credit-prediction train_labels.zip\n", + "download_link = \"https://github.com/kubeflow/examples/blob/master/american-express-default-kaggle-competition/data/train_labels.zip?raw=true\"\n", + "wget.download(download_link, f'{data_path}/train_labels.zip')\n", + "\n", + "# extract Amex-credit-prediction.zip to data_path\n", + "with zipfile.ZipFile(f'{data_path}/train_labels.zip','r') as zip_ref:\n", + " zip_ref.extractall(data_path)\n", + " \n", + "# delete zipfiles\n", + "subprocess.run(['rm', f'{dataset}.zip'])\n", + "subprocess.run(['rm', f'{data_path}/train_labels.zip'])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Load the dataset\n", + "\n", + "First, let us load and analyze the data.\n", + "\n", + "The data is in csv format, thus, we use the handy read_csv pandas method." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "tags": [ + "block:load_data", + "prev:download_data" + ] + }, + "outputs": [], + "source": [ + "TRAIN_CSV = (f'{data_path}/train.parquet')\n", + "TEST_CSV = f'{data_path}/test.parquet'\n", + "TARGET_CSV = f'{data_path}/train_labels.csv'" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "target shape: (458913,)\n" + ] + } + ], + "source": [ + "df_train = pd.read_parquet(TRAIN_CSV)\n", + "df_test = pd.read_parquet(TEST_CSV)\n", + "target = pd.read_csv(TARGET_CSV).target.values\n", + "print(f\"target shape: {target.shape}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(5531451, 190)" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "customer_ID 0\n", + "S_2 0\n", + "P_2 45985\n", + "D_39 0\n", + "B_1 0\n", + " ... \n", + "D_141 101548\n", + "D_142 4587043\n", + "D_143 0\n", + "D_144 40727\n", + "D_145 0\n", + "Length: 190, dtype: int64" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train.isna().sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "### Define Helper Functions" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "tags": [ + "functions" + ] + }, + "outputs": [], + "source": [ + "# @yunchonggan's fast metric implementation\n", + "# From https://www.kaggle.com/competitions/amex-default-prediction/discussion/328020\n", + "def amex_metric(y_true: np.array, y_pred: np.array) -> float:\n", + "\n", + " # count of positives and negatives\n", + " n_pos = y_true.sum()\n", + " n_neg = y_true.shape[0] - n_pos\n", + "\n", + " # sorting by descring prediction values\n", + " indices = np.argsort(y_pred)[::-1]\n", + " preds, target = y_pred[indices], y_true[indices]\n", + "\n", + " # filter the top 4% by cumulative row weights\n", + " weight = 20.0 - target * 19.0\n", + " cum_norm_weight = (weight / weight.sum()).cumsum()\n", + " four_pct_filter = cum_norm_weight <= 0.04\n", + "\n", + " # default rate captured at 4%\n", + " d = target[four_pct_filter].sum() / n_pos\n", + "\n", + " # weighted gini coefficient\n", + " lorentz = (target / n_pos).cumsum()\n", + " gini = ((lorentz - cum_norm_weight) * weight).sum()\n", + "\n", + " # max weighted gini coefficient\n", + " gini_max = 10 * n_neg * (1 - 19 / (n_pos + 20 * n_neg))\n", + "\n", + " # normalized weighted gini coefficient\n", + " g = gini / gini_max\n", + "\n", + " return 0.5 * (g + d)\n", + "\n", + "def lgb_amex_metric(y_true, y_pred):\n", + " \"\"\"The competition metric with lightgbm's calling convention\"\"\"\n", + " return ('amex_metric_score',\n", + " amex_metric(y_true, y_pred),\n", + " True)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Feature Engineering" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "tags": [ + "block:feature_engineering", + "prev:load_data" + ] + }, + "outputs": [], + "source": [ + "# feature engineering gotten from https://www.kaggle.com/code/ambrosm/amex-lightgbm-quickstart\n", + "def get_features(df, \n", + " features_avg, \n", + " features_min, \n", + " features_max, \n", + " features_last\n", + " ):\n", + " '''\n", + " This function takes a dataframe with all features and returns the aggregated feature grouped by the customer id.\n", + " \n", + " df - dataframe\n", + " '''\n", + " cid = pd.Categorical(df.pop('customer_ID'), ordered=True) # get customer id\n", + " last = (cid != np.roll(cid, -1)) # mask for last statement of every customer\n", + " \n", + " df_avg = (df\n", + " .groupby(cid)\n", + " .mean()[features_avg]\n", + " .rename(columns={f: f\"{f}_avg\" for f in features_avg})\n", + " ) \n", + " \n", + " df_min = (df\n", + " .groupby(cid)\n", + " .min()[features_min]\n", + " .rename(columns={f: f\"{f}_min\" for f in features_min})\n", + " )\n", + " gc.collect()\n", + " print('Computed min')\n", + " \n", + " df_max = (df\n", + " .groupby(cid)\n", + " .max()[features_max]\n", + " .rename(columns={f: f\"{f}_max\" for f in features_max})\n", + " )\n", + " gc.collect()\n", + " print('Computed max')\n", + " \n", + " df = (df.loc[last, features_last]\n", + " .rename(columns={f: f\"{f}_last\" for f in features_last})\n", + " .set_index(np.asarray(cid[last]))\n", + " )\n", + " gc.collect()\n", + " print('Computed last')\n", + " \n", + " df_ = pd.concat([df, df_min, df_max, df_avg], axis=1, )\n", + " \n", + " del df, df_avg, df_min, df_max, cid, last\n", + " \n", + " return df_" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "features_avg = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', \n", + " 'B_16', 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_28', 'B_29', 'B_30', \n", + " 'B_32', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', \n", + " 'D_45', 'D_46', 'D_47', 'D_48', 'D_50', 'D_51', 'D_53', 'D_54', 'D_55', 'D_58', 'D_59', 'D_60', 'D_61', \n", + " 'D_62', 'D_65', 'D_66', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_75', 'D_76', 'D_77', 'D_78', \n", + " 'D_80', 'D_82', 'D_84', 'D_86', 'D_91', 'D_92', 'D_94', 'D_96', 'D_103', 'D_104', 'D_108', 'D_112', 'D_113', \n", + " 'D_114', 'D_115', 'D_117', 'D_118', 'D_119', 'D_120', 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', \n", + " 'D_128', 'D_129', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', 'D_140', 'D_141', 'D_142', 'D_144', \n", + " 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_2', 'R_3', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_14', 'R_15', 'R_16', \n", + " 'R_17', 'R_20', 'R_21', 'R_22', 'R_24', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_9', 'S_11', 'S_12', 'S_13', \n", + " 'S_15', 'S_16', 'S_18', 'S_22', 'S_23', 'S_25', 'S_26']\n", + "features_min = ['B_2', 'B_4', 'B_5', 'B_9', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', 'B_19', 'B_20', 'B_28', 'B_29', 'B_33', 'B_36', \n", + " 'B_42', 'D_39', 'D_41', 'D_42', 'D_45', 'D_46', 'D_48', 'D_50', 'D_51', 'D_53', 'D_55', 'D_56', 'D_58', 'D_59', \n", + " 'D_60', 'D_62', 'D_70', 'D_71', 'D_74', 'D_75', 'D_78', 'D_83', 'D_102', 'D_112', 'D_113', 'D_115', 'D_118', 'D_119', \n", + " 'D_121', 'D_122', 'D_128', 'D_132', 'D_140', 'D_141', 'D_144', 'D_145', 'P_2', 'P_3', 'R_1', 'R_27', 'S_3', 'S_5', \n", + " 'S_7', 'S_9', 'S_11', 'S_12', 'S_23', 'S_25']\n", + "features_max = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', \n", + " 'B_18', 'B_19', 'B_21', 'B_23', 'B_24', 'B_25', 'B_29', 'B_30', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_42', 'D_39', \n", + " 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', 'D_48', 'D_49', 'D_50', 'D_52', 'D_55', 'D_56', 'D_58', 'D_59', \n", + " 'D_60', 'D_61', 'D_63', 'D_64', 'D_65', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_76', 'D_77', 'D_78', 'D_80', 'D_82', \n", + " 'D_84', 'D_91', 'D_102', 'D_105', 'D_107', 'D_110', 'D_111', 'D_112', 'D_115', 'D_116', 'D_117', 'D_118', 'D_119', \n", + " 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', 'D_128', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', \n", + " 'D_138', 'D_140', 'D_141', 'D_142', 'D_144', 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_3', 'R_5', 'R_6', 'R_7', 'R_8', \n", + " 'R_10', 'R_11', 'R_14', 'R_17', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_7', 'S_8', 'S_11', 'S_12', 'S_13', 'S_15', 'S_16', \n", + " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']\n", + "features_last = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', \n", + " 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_26', 'B_28', 'B_29', 'B_30', 'B_32', 'B_33', \n", + " 'B_36', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', \n", + " 'D_48', 'D_49', 'D_50', 'D_51', 'D_52', 'D_53', 'D_54', 'D_55', 'D_56', 'D_58', 'D_59', 'D_60', 'D_61', 'D_62', 'D_63', \n", + " 'D_64', 'D_65', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_75', 'D_76', 'D_77', 'D_78', 'D_79', 'D_80', 'D_81', 'D_82', \n", + " 'D_83', 'D_86', 'D_91', 'D_96', 'D_105', 'D_106', 'D_112', 'D_114', 'D_119', 'D_120', 'D_121', 'D_122', 'D_124', 'D_125', \n", + " 'D_126', 'D_127', 'D_130', 'D_131', 'D_132', 'D_133', 'D_134', 'D_138', 'D_140', 'D_141', 'D_142', 'D_145', 'P_2', 'P_3', \n", + " 'P_4', 'R_1', 'R_2', 'R_3', 'R_4', 'R_5', 'R_6', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_12', 'R_13', 'R_14', 'R_15', \n", + " 'R_19', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_8', 'S_9', 'S_11', 'S_12', 'S_13', 'S_16', 'S_19', 'S_20', \n", + " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# apply feature engineering function\n", + "train = get_features(df_train, features_avg, features_min, features_max, features_last)\n", + "test = get_features(df_test, features_avg, features_min, features_max, features_last)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# check null values\n", + "train.isna().any()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Modelling: StratifiedKFold\n", + "\n", + "We cross-validate with a six-fold StratifiedKFold to handle the imbalanced nature of the target.\n", + "\n", + "Lightgbm handles null values efficiently." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "block:modelling", + "prev:feature_engineering" + ] + }, + "outputs": [], + "source": [ + "# Cross-validation\n", + "\n", + "features = [f for f in train.columns if f != 'customer_ID' and f != 'target']\n", + "\n", + "print(f\"{len(features)} features\")\n", + "\n", + "score_list = [] # lgbm score per fold\n", + "y_pred_list = [] # fold predictions list\n", + "\n", + "# init StratifiedKFold\n", + "kf = StratifiedKFold(n_splits=4)\n", + "\n", + "for fold, (idx_tr, idx_va) in enumerate(kf.split(train, target)):\n", + " \n", + " X_tr, X_va, y_tr, y_va, model = None, None, None, None, None\n", + "\n", + " X_tr = train.iloc[idx_tr][features]\n", + " X_va = train.iloc[idx_va][features]\n", + " y_tr = target[idx_tr]\n", + " y_va = target[idx_va]\n", + " \n", + " # init model\n", + " model = LGBMClassifier(n_estimators=int(N_EST),\n", + " learning_rate=float(LR), \n", + " random_state=2022)\n", + " # fit model\n", + " model.fit(X_tr, y_tr,\n", + " eval_set = [(X_va, y_va)], \n", + " eval_metric=[lgb_amex_metric],\n", + " verbose = 20,\n", + " early_stopping_rounds=30)\n", + " \n", + " X_tr, y_tr = None, None\n", + " \n", + " # fold validation set predictions\n", + " y_va_pred = model.predict_proba(X_va, raw_score=True)\n", + " \n", + " # model score\n", + " score = amex_metric(y_va, y_va_pred)\n", + "\n", + " print(f\"Score = {score}\")\n", + " score_list.append(score)\n", + " \n", + " # test set predictions\n", + " y_pred_list.append(model.predict_proba(test[features], raw_score=True))\n", + " \n", + " print(f\"Fold {fold}\") \n", + "\n", + "# save model\n", + "joblib.dump(model, 'lgb.jl')\n", + "print(f\"OOF Score: {np.mean(score_list):.5f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# feature importance for top 30 features\n", + "fea_imp = pd.DataFrame({'imp':model.feature_importances_, 'col': features})\n", + "fea_imp = fea_imp.sort_values(['imp', 'col'], ascending=[True, False]).iloc[-30:]\n", + "_ = fea_imp.plot(kind='barh', x='col', y='imp', figsize=(20, 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Evaluation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "block:evaluation_result", + "prev:modelling" + ] + }, + "outputs": [], + "source": [ + "model = joblib.load('lgb.jl')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "binary_logloss = model.booster_.best_score.get('valid_0').get('binary_logloss')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "amex_metric_score = model.booster_.best_score.get('valid_0').get('amex_metric_score')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "pipeline-metrics" + ] + }, + "outputs": [], + "source": [ + "print(binary_logloss)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "pipeline-metrics" + ] + }, + "outputs": [], + "source": [ + "print(amex_metric_score)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Submission" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "sub = pd.DataFrame({'customer_ID': test.index,\n", + " 'prediction': np.mean(y_pred_list, axis=0)})\n", + "sub.to_csv('submission.csv', index=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "sub" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "kubeflow_notebook": { + "autosnapshot": true, + "experiment": { + "id": "new", + "name": "american-express-defaul-prediction" + }, + "experiment_name": "american-express-defaul-prediction", + "katib_metadata": { + "algorithm": { + "algorithmName": "grid" + }, + "maxFailedTrialCount": 3, + "maxTrialCount": 12, + "objective": { + "objectiveMetricName": "", + "type": "minimize" + }, + "parallelTrialCount": 3, + "parameters": [] + }, + "katib_run": false, + "pipeline_description": "predicting credit default", + "pipeline_name": "american-express-defaul-prediction-pipeline", + "snapshot_volumes": true, + "steps_defaults": [ + "label:access-ml-pipeline:true", + "label:kaggle-secret:true", + "label:access-rok:true" + ], + "volume_access_mode": "rwm", + "volumes": [ + { + "annotations": [], + "mount_point": "/home/jovyan", + "name": "test-workspace-qtvmt", + "size": 32, + "size_type": "Gi", + "snapshot": false, + "type": "clone" + } + ] + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/american-express-default-kaggle-competition/american-express-default-prediction-kfp.ipynb b/american-express-default-kaggle-competition/american-express-default-prediction-kfp.ipynb index 01ffdac43..6f585c8c5 100644 --- a/american-express-default-kaggle-competition/american-express-default-prediction-kfp.ipynb +++ b/american-express-default-kaggle-competition/american-express-default-prediction-kfp.ipynb @@ -1,779 +1,779 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "# 🪙 American Express - Default Prediction Competition Vanilla KFP Pipeline\n", - "![](./images/background.jpg)\n", - "\n", - "---\n", - "\n", - "In this [Kaggle competition](https://www.kaggle.com/competitions/g-research-crypto-forecasting/overview), you'll use your machine learning expertise to predict credit default. This competition is hosted by American Express. \n", - "\n", - "> American Express is a globally integrated payments company. The largest payment card issuer in the world, they provide customers with access to products, insights, and experiences that enrich lives and build business success.\n", - "\n", - "The dataset provided is an industrial scale data set of about 5.5 million rows. It has been pre-processed and converted to a lightweight version by raddar for ease of training and better result. This dataset is available in a [parquet format][1].\n", - "\n", - "[1]: https://www.kaggle.com/datasets/raddar/amex-data-integer-dtypes-parquet-format" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Install relevant libraries\n", - "\n", - "\n", - ">Update pip `pip install --user --upgrade pip`\n", - "\n", - ">Install and upgrade kubeflow sdk `pip install kfp --upgrade --user --quiet`\n", - "\n", - "You may need to restart your notebook kernel after installing the kfp sdk" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: pip in /usr/local/lib/python3.6/dist-packages (21.3.1)\n" - ] - } - ], - "source": [ - "!pip install --user --upgrade pip" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "!pip install kfp --upgrade --user --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Name: kfp\n", - "Version: 1.8.11\n", - "Summary: KubeFlow Pipelines SDK\n", - "Home-page: https://github.com/kubeflow/pipelines\n", - "Author: The Kubeflow Authors\n", - "Author-email: \n", - "License: UNKNOWN\n", - "Location: /home/jovyan/.local/lib/python3.6/site-packages\n", - "Requires: absl-py, click, cloudpickle, dataclasses, Deprecated, docstring-parser, fire, google-api-python-client, google-auth, google-cloud-storage, jsonschema, kfp-pipeline-spec, kfp-server-api, kubernetes, protobuf, pydantic, PyYAML, requests-toolbelt, strip-hints, tabulate, typer, typing-extensions, uritemplate\n", - "Required-by: kubeflow-kale\n" - ] - } - ], - "source": [ - "# confirm the kfp sdk\n", - "! pip show kfp" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "tags": [ - "imports" - ] - }, - "outputs": [], - "source": [ - "import kfp\n", - "import kfp.components as comp\n", - "import kfp.dsl as dsl\n", - "from kfp.components import OutputPath\n", - "from typing import NamedTuple" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "# Kubeflow pipeline component creation\n", - "\n", - "## Download the dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# load data step\n", - "def download_data(dataset, \n", - " data_path):\n", - " \n", - " # install the necessary libraries\n", - " import os, sys, subprocess, zipfile, pickle;\n", - " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','kaggle'])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','wget'])\n", - " \n", - " # import libraries\n", - " import pandas as pd\n", - " import wget\n", - "\n", - " # setup kaggle environment for data download\n", - " with open('/secret/kaggle-secret/password', 'r') as file:\n", - " kaggle_key = file.read().rstrip()\n", - " with open('/secret/kaggle-secret/username', 'r') as file:\n", - " kaggle_user = file.read().rstrip()\n", - " \n", - " os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", - " \n", - " # create data_path directory\n", - " if not os.path.exists(data_path):\n", - " os.makedirs(data_path)\n", - " \n", - " # download kaggle's Amex-credit-prediction data\n", - " subprocess.run([\"kaggle\",\"datasets\", \"download\", \"-d\", f'raddar/{dataset}'])\n", - " \n", - " # extract Amex-credit-prediction.zip to data_path\n", - " with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", - " zip_ref.extractall(data_path)\n", - "\n", - " # download kaggle's Amex-credit-prediction train_labels.zip\n", - " download_link = \"https://github.com/kubeflow/examples/blob/master/american-express-default-kaggle-competition/data/train_labels.zip?raw=true\"\n", - " \n", - " wget.download(download_link, f'{data_path}/train_labels.zip')\n", - "\n", - " # extract Amex-credit-prediction.zip to data_path\n", - " with zipfile.ZipFile(f'{data_path}/train_labels.zip','r') as zip_ref:\n", - " zip_ref.extractall(data_path)\n", - "\n", - " # delete zipfiles\n", - " subprocess.run(['rm', f'{dataset}.zip'])\n", - " subprocess.run(['rm', f'{data_path}/train_labels.zip'])\n", - " return(print('Done!'))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Load Data" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "# load data step\n", - "def load_data(data_path):\n", - " \n", - " # install the necessary libraries\n", - " import os, sys, subprocess, pickle;\n", - " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','pyarrow'])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','fastparquet'])\n", - " \n", - " # import libraries\n", - " import pandas as pd\n", - "\n", - " TRAIN_CSV = (f'{data_path}/train.parquet')\n", - " TEST_CSV = f'{data_path}/test.parquet'\n", - " TARGET_CSV = f'{data_path}/train_labels.csv'\n", - " \n", - " # read parquet TRAIN, TEST and TARGET_CSV\n", - " df_train = pd.read_parquet(TRAIN_CSV)\n", - " df_test = pd.read_parquet(TEST_CSV)\n", - " target = pd.read_csv(TARGET_CSV).target.values\n", - " print(f\"target shape: {target.shape}\")\n", - " \n", - " \n", - " # Save all data as a pickle file to be used by the feature_engineering component.\n", - " with open(f'{data_path}/df_data', 'wb') as f:\n", - " pickle.dump((df_train, target, df_test), f)\n", - " \n", - " return(print('Done!'))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Feature Engineering" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "# feature engineering step\n", - "\n", - "def feature_engineering(data_path):\n", - " \n", - " # install the necessary libraries\n", - " import sys, subprocess;\n", - " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", - " \n", - " # import Library\n", - " import os, pickle, gc\n", - " import numpy as np\n", - " import pandas as pd\n", - "\n", - " # loading data\n", - " with open(f'{data_path}/df_data', 'rb') as f:\n", - " df_train, target, df_test = pickle.load(f)\n", - " \n", - " # feature engineering gotten from https://www.kaggle.com/code/ambrosm/amex-lightgbm-quickstart\n", - " def get_features(df, \n", - " features_avg, \n", - " features_min, \n", - " features_max, \n", - " features_last\n", - " ):\n", - " '''\n", - " This function takes a dataframe with all features and returns the aggregated feature grouped by the customer id.\n", - "\n", - " df - dataframe\n", - " '''\n", - " cid = pd.Categorical(df.pop('customer_ID'), ordered=True) # get customer id\n", - " last = (cid != np.roll(cid, -1)) # mask for last statement of every customer\n", - "\n", - " df_avg = (df\n", - " .groupby(cid)\n", - " .mean()[features_avg]\n", - " .rename(columns={f: f\"{f}_avg\" for f in features_avg})\n", - " ) \n", - "\n", - " df_min = (df\n", - " .groupby(cid)\n", - " .min()[features_min]\n", - " .rename(columns={f: f\"{f}_min\" for f in features_min})\n", - " )\n", - " gc.collect()\n", - " print('Computed min')\n", - "\n", - " df_max = (df\n", - " .groupby(cid)\n", - " .max()[features_max]\n", - " .rename(columns={f: f\"{f}_max\" for f in features_max})\n", - " )\n", - " gc.collect()\n", - " print('Computed max')\n", - "\n", - " df = (df.loc[last, features_last]\n", - " .rename(columns={f: f\"{f}_last\" for f in features_last})\n", - " .set_index(np.asarray(cid[last]))\n", - " )\n", - " gc.collect()\n", - " print('Computed last')\n", - "\n", - " df_ = pd.concat([df, df_min, df_max, df_avg], axis=1, )\n", - "\n", - " del df, df_avg, df_min, df_max, cid, last\n", - "\n", - " return df_\n", - " \n", - " features_avg = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', \n", - " 'B_16', 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_28', 'B_29', 'B_30', \n", - " 'B_32', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', \n", - " 'D_45', 'D_46', 'D_47', 'D_48', 'D_50', 'D_51', 'D_53', 'D_54', 'D_55', 'D_58', 'D_59', 'D_60', 'D_61', \n", - " 'D_62', 'D_65', 'D_66', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_75', 'D_76', 'D_77', 'D_78', \n", - " 'D_80', 'D_82', 'D_84', 'D_86', 'D_91', 'D_92', 'D_94', 'D_96', 'D_103', 'D_104', 'D_108', 'D_112', 'D_113', \n", - " 'D_114', 'D_115', 'D_117', 'D_118', 'D_119', 'D_120', 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', \n", - " 'D_128', 'D_129', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', 'D_140', 'D_141', 'D_142', 'D_144', \n", - " 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_2', 'R_3', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_14', 'R_15', 'R_16', \n", - " 'R_17', 'R_20', 'R_21', 'R_22', 'R_24', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_9', 'S_11', 'S_12', 'S_13', \n", - " 'S_15', 'S_16', 'S_18', 'S_22', 'S_23', 'S_25', 'S_26']\n", - " features_min = ['B_2', 'B_4', 'B_5', 'B_9', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', 'B_19', 'B_20', 'B_28', 'B_29', 'B_33', 'B_36', \n", - " 'B_42', 'D_39', 'D_41', 'D_42', 'D_45', 'D_46', 'D_48', 'D_50', 'D_51', 'D_53', 'D_55', 'D_56', 'D_58', 'D_59', \n", - " 'D_60', 'D_62', 'D_70', 'D_71', 'D_74', 'D_75', 'D_78', 'D_83', 'D_102', 'D_112', 'D_113', 'D_115', 'D_118', 'D_119', \n", - " 'D_121', 'D_122', 'D_128', 'D_132', 'D_140', 'D_141', 'D_144', 'D_145', 'P_2', 'P_3', 'R_1', 'R_27', 'S_3', 'S_5', \n", - " 'S_7', 'S_9', 'S_11', 'S_12', 'S_23', 'S_25']\n", - " features_max = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', \n", - " 'B_18', 'B_19', 'B_21', 'B_23', 'B_24', 'B_25', 'B_29', 'B_30', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_42', 'D_39', \n", - " 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', 'D_48', 'D_49', 'D_50', 'D_52', 'D_55', 'D_56', 'D_58', 'D_59', \n", - " 'D_60', 'D_61', 'D_63', 'D_64', 'D_65', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_76', 'D_77', 'D_78', 'D_80', 'D_82', \n", - " 'D_84', 'D_91', 'D_102', 'D_105', 'D_107', 'D_110', 'D_111', 'D_112', 'D_115', 'D_116', 'D_117', 'D_118', 'D_119', \n", - " 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', 'D_128', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', \n", - " 'D_138', 'D_140', 'D_141', 'D_142', 'D_144', 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_3', 'R_5', 'R_6', 'R_7', 'R_8', \n", - " 'R_10', 'R_11', 'R_14', 'R_17', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_7', 'S_8', 'S_11', 'S_12', 'S_13', 'S_15', 'S_16', \n", - " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']\n", - " features_last = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', \n", - " 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_26', 'B_28', 'B_29', 'B_30', 'B_32', 'B_33', \n", - " 'B_36', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', \n", - " 'D_48', 'D_49', 'D_50', 'D_51', 'D_52', 'D_53', 'D_54', 'D_55', 'D_56', 'D_58', 'D_59', 'D_60', 'D_61', 'D_62', 'D_63', \n", - " 'D_64', 'D_65', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_75', 'D_76', 'D_77', 'D_78', 'D_79', 'D_80', 'D_81', 'D_82', \n", - " 'D_83', 'D_86', 'D_91', 'D_96', 'D_105', 'D_106', 'D_112', 'D_114', 'D_119', 'D_120', 'D_121', 'D_122', 'D_124', 'D_125', \n", - " 'D_126', 'D_127', 'D_130', 'D_131', 'D_132', 'D_133', 'D_134', 'D_138', 'D_140', 'D_141', 'D_142', 'D_145', 'P_2', 'P_3', \n", - " 'P_4', 'R_1', 'R_2', 'R_3', 'R_4', 'R_5', 'R_6', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_12', 'R_13', 'R_14', 'R_15', \n", - " 'R_19', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_8', 'S_9', 'S_11', 'S_12', 'S_13', 'S_16', 'S_19', 'S_20', \n", - " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']\n", - " \n", - " # apply feature engineering function\n", - " train = get_features(df_train, features_avg, features_min, features_max, features_last)\n", - " test = get_features(df_test, features_avg, features_min, features_max, features_last)\n", - "\n", - " # save the feature engineered data as a pickle file to be used by the modeling component.\n", - " with open(f'{data_path}/features_df', 'wb') as f:\n", - " pickle.dump((train, test, target), f)\n", - " \n", - " return(print('Done!')) " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.01421, - "end_time": "2022-04-17T07:17:13.396620", - "exception": false, - "start_time": "2022-04-17T07:17:13.382410", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "## Modelling\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "# modeling step\n", - "\n", - "def modeling(data_path):\n", - " \n", - " # install the necessary libraries\n", - " import sys, subprocess;\n", - " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','scikit-learn'])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','lightgbm'])\n", - " \n", - " # import Library\n", - " import os, pickle, joblib, warnings;\n", - " import pandas as pd\n", - " import numpy as np\n", - " from sklearn.model_selection import StratifiedKFold\n", - " from lightgbm import LGBMClassifier\n", - " warnings.filterwarnings(\"ignore\")\n", - " \n", - " # loading data\n", - " with open(f'{data_path}/features_df', 'rb') as f:\n", - " train, test, target = pickle.load(f)\n", - " \n", - " # define the evaluation metric\n", - " # From https://www.kaggle.com/competitions/amex-default-prediction/discussion/328020\n", - " def amex_metric(y_true: np.array, y_pred: np.array) -> float:\n", - "\n", - " # count of positives and negatives\n", - " n_pos = y_true.sum()\n", - " n_neg = y_true.shape[0] - n_pos\n", - "\n", - " # sorting by descring prediction values\n", - " indices = np.argsort(y_pred)[::-1]\n", - " preds, target = y_pred[indices], y_true[indices]\n", - "\n", - " # filter the top 4% by cumulative row weights\n", - " weight = 20.0 - target * 19.0\n", - " cum_norm_weight = (weight / weight.sum()).cumsum()\n", - " four_pct_filter = cum_norm_weight <= 0.04\n", - "\n", - " # default rate captured at 4%\n", - " d = target[four_pct_filter].sum() / n_pos\n", - "\n", - " # weighted gini coefficient\n", - " lorentz = (target / n_pos).cumsum()\n", - " gini = ((lorentz - cum_norm_weight) * weight).sum()\n", - "\n", - " # max weighted gini coefficient\n", - " gini_max = 10 * n_neg * (1 - 19 / (n_pos + 20 * n_neg))\n", - "\n", - " # normalized weighted gini coefficient\n", - " g = gini / gini_max\n", - "\n", - " return 0.5 * (g + d)\n", - "\n", - " def lgb_amex_metric(y_true, y_pred):\n", - " \"\"\"The competition metric with lightgbm's calling convention\"\"\"\n", - " return ('amex_metric_score',\n", - " amex_metric(y_true, y_pred),\n", - " True)\n", - " \n", - " # Cross-validation\n", - "\n", - " features = [f for f in train.columns if f != 'customer_ID' and f != 'target']\n", - "\n", - " print(f\"{len(features)} features\")\n", - "\n", - " score_list = [] # lgbm score per fold\n", - " y_pred_list = [] # fold predictions list\n", - "\n", - " # init StratifiedKFold\n", - " kf = StratifiedKFold(n_splits=4)\n", - "\n", - " for fold, (idx_tr, idx_va) in enumerate(kf.split(train, target)):\n", - "\n", - " X_tr, X_va, y_tr, y_va, model = None, None, None, None, None\n", - "\n", - " X_tr = train.iloc[idx_tr][features]\n", - " X_va = train.iloc[idx_va][features]\n", - " y_tr = target[idx_tr]\n", - " y_va = target[idx_va]\n", - "\n", - " # init model\n", - " model = LGBMClassifier(n_estimators=30,\n", - " learning_rate=0.1, \n", - " num_leaves=100,\n", - " random_state=2022)\n", - " # fit model\n", - " model.fit(X_tr, y_tr,\n", - " eval_set = [(X_va, y_va)], \n", - " eval_metric=[lgb_amex_metric],\n", - " verbose = 20,\n", - " early_stopping_rounds=30)\n", - "\n", - " X_tr, y_tr = None, None\n", - "\n", - " # fold validation set predictions\n", - " y_va_pred = model.predict_proba(X_va, raw_score=True)\n", - "\n", - " # model score\n", - " score = amex_metric(y_va, y_va_pred)\n", - "\n", - " print(f\"Score = {score}\")\n", - " score_list.append(score)\n", - "\n", - " # test set predictions\n", - " y_pred_list.append(model.predict_proba(test[features], raw_score=True))\n", - "\n", - " print(f\"Fold {fold}\") \n", - "\n", - " # save model\n", - " joblib.dump(model, f'{data_path}/lgb.jl')\n", - " \n", - " return(print('Done!')) " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.01428, - "end_time": "2022-04-17T07:17:23.959655", - "exception": false, - "start_time": "2022-04-17T07:17:23.945375", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "## Evaluation" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "# evaluation step\n", - "\n", - "def evaluation_result(data_path, \n", - " metrics_path: OutputPath(str)) -> NamedTuple(\"EvaluationOutput\", [(\"mlpipeline_metrics\", \"Metrics\")]):\n", - " \n", - " # import Library\n", - " import sys, subprocess;\n", - " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", - " subprocess.run([sys.executable, '-m', 'pip', 'install','lightgbm'])\n", - " import json;\n", - " from collections import namedtuple\n", - " import joblib\n", - " import lightgbm as lgb\n", - " from lightgbm import LGBMRegressor\n", - " \n", - " # load model\n", - " model = joblib.load(f'{data_path}/lgb.jl')\n", - "\n", - " # model evaluation\n", - " binary_logloss = model.booster_.best_score.get('valid_0').get('binary_logloss')\n", - " amex_metric_score = model.booster_.best_score.get('valid_0').get('amex_metric_score')\n", - " \n", - " # create kubeflow metric metadata for UI \n", - " metrics = {\n", - " 'metrics': [\n", - " {'name': 'binary-logloss',\n", - " 'numberValue': binary_logloss,\n", - " 'format': 'RAW'},\n", - " {'name': 'amex-metric-score',\n", - " 'numberValue': amex_metric_score,\n", - " 'format': 'RAW'}\n", - " ]\n", - " }\n", - " \n", - "\n", - " with open(metrics_path, \"w\") as f:\n", - " json.dump(metrics, f)\n", - "\n", - " output_tuple = namedtuple(\"EvaluationOutput\", [\"mlpipeline_metrics\"])\n", - "\n", - " return output_tuple(json.dumps(metrics))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create pipeline components \n", - "\n", - "using `create_component_from_func`" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "# create light weight components\n", - "download_op = comp.create_component_from_func(download_data,base_image=\"python:3.7.1\")\n", - "load_op = comp.create_component_from_func(load_data,base_image=\"python:3.7.1\")\n", - "feature_eng_op = comp.create_component_from_func(feature_engineering,base_image=\"python:3.7.1\")\n", - "modeling_op = comp.create_component_from_func(modeling, base_image=\"python:3.7.1\")\n", - "evaluation_op = comp.create_component_from_func(evaluation_result, base_image=\"python:3.7.1\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Kubeflow pipeline creation" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "# define pipeline\n", - "@dsl.pipeline(name=\"american-express-default-prediction-pipeline\", \n", - " description=\"predicting credit default.\")\n", - "\n", - "# Define parameters to be fed into pipeline\n", - "def american_express_default_prediction_pipeline(\n", - " dataset: str,\n", - " data_path: str\n", - " ):\n", - " # Define volume to share data between components.\n", - " vop = dsl.VolumeOp(\n", - " name=\"create_data_volume\",\n", - " resource_name=\"data-volume\", \n", - " size=\"24Gi\", \n", - " modes=dsl.VOLUME_MODE_RWO)\n", - " \n", - " \n", - " # Create download container.\n", - " download_container = download_op(dataset, data_path)\\\n", - " .add_pvolumes({data_path: vop.volume}).add_pod_label(\"kaggle-secret\", \"true\")\n", - " # Create load container.\n", - " load_container = load_op(data_path)\\\n", - " .add_pvolumes({data_path: download_container.pvolume})\n", - " # Create feature engineering container.\n", - " feat_eng_container = feature_eng_op(data_path)\\\n", - " .add_pvolumes({data_path: load_container.pvolume})\n", - " # Create modeling container.\n", - " modeling_container = modeling_op(data_path)\\\n", - " .add_pvolumes({data_path: feat_eng_container.pvolume})\n", - " # Create prediction container.\n", - " evaluation_container = evaluation_op(data_path).add_pvolumes({data_path: modeling_container.pvolume})" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "# create client that would enable communication with the Pipelines API server \n", - "client = kfp.Client()" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "# arguments\n", - "dataset = \"amex-data-integer-dtypes-parquet-format\"\n", - "data_path = \"/mnt\"" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "Experiment details." - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "Run details." - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "pipeline_func = american_express_default_prediction_pipeline\n", - "\n", - "experiment_name = 'american_express_default_prediction_pipeline_lightweight'\n", - "run_name = pipeline_func.__name__ + ' run'\n", - "\n", - "arguments = {\n", - " \"dataset\": dataset,\n", - " \"data_path\": data_path\n", - " }\n", - "\n", - "# Compile pipeline to generate compressed YAML definition of the pipeline.\n", - "kfp.compiler.Compiler().compile(pipeline_func, \n", - " '{}.zip'.format(experiment_name))\n", - "\n", - "# Submit pipeline directly from pipeline function\n", - "run_result = client.create_run_from_pipeline_func(pipeline_func, \n", - " experiment_name=experiment_name, \n", - " run_name=run_name, \n", - " arguments=arguments\n", - " )\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kubeflow_notebook": { - "autosnapshot": true, - "experiment": { - "id": "2efb8e27-3b2e-439b-a53c-b1f9d7b94cfc", - "name": "g-research-crypto-forecasting" - }, - "experiment_name": "g-research-crypto-forecasting", - "katib_metadata": { - "algorithm": { - "algorithmName": "grid" - }, - "maxFailedTrialCount": 3, - "maxTrialCount": 12, - "objective": { - "objectiveMetricName": "", - "type": "minimize" - }, - "parallelTrialCount": 3, - "parameters": [] - }, - "katib_run": false, - "pipeline_description": "Forecasting short term returns in 14 popular cryptocurrencies.", - "pipeline_name": "g-research-crypto-forecasting-pipeline", - "snapshot_volumes": true, - "steps_defaults": [ - "label:access-ml-pipeline:true", - "label:kaggle-secret:true", - "label:access-rok:true" - ], - "volume_access_mode": "rwm", - "volumes": [ - { - "annotations": [], - "mount_point": "/home/jovyan", - "name": "test-workspace-qtvmt", - "size": 32, - "size_type": "Gi", - "snapshot": false, - "type": "clone" - } - ] - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.9" - }, - "papermill": { - "default_parameters": {}, - "duration": 32.012084, - "end_time": "2022-04-17T07:17:25.053666", - "environment_variables": {}, - "exception": null, - "input_path": "__notebook__.ipynb", - "output_path": "__notebook__.ipynb", - "parameters": {}, - "start_time": "2022-04-17T07:16:53.041582", - "version": "2.3.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# 🪙 American Express - Default Prediction Competition Vanilla KFP Pipeline\n", + "![](./images/background.jpg)\n", + "\n", + "---\n", + "\n", + "In this [Kaggle competition](https://www.kaggle.com/competitions/g-research-crypto-forecasting/overview), you'll use your machine learning expertise to predict credit default. This competition is hosted by American Express. \n", + "\n", + "> American Express is a globally integrated payments company. The largest payment card issuer in the world, they provide customers with access to products, insights, and experiences that enrich lives and build business success.\n", + "\n", + "The dataset provided is an industrial scale data set of about 5.5 million rows. It has been pre-processed and converted to a lightweight version by raddar for ease of training and better result. This dataset is available in a [parquet format][1].\n", + "\n", + "[1]: https://www.kaggle.com/datasets/raddar/amex-data-integer-dtypes-parquet-format" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Install relevant libraries\n", + "\n", + "\n", + ">Update pip `pip install --user --upgrade pip`\n", + "\n", + ">Install and upgrade kubeflow sdk `pip install kfp --upgrade --user --quiet`\n", + "\n", + "You may need to restart your notebook kernel after installing the kfp sdk" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: pip in /usr/local/lib/python3.6/dist-packages (21.3.1)\n" + ] + } + ], + "source": [ + "!pip install --user --upgrade pip" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install kfp --upgrade --user --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Name: kfp\n", + "Version: 1.8.11\n", + "Summary: KubeFlow Pipelines SDK\n", + "Home-page: https://github.com/kubeflow/pipelines\n", + "Author: The Kubeflow Authors\n", + "Author-email: \n", + "License: UNKNOWN\n", + "Location: /home/jovyan/.local/lib/python3.6/site-packages\n", + "Requires: absl-py, click, cloudpickle, dataclasses, Deprecated, docstring-parser, fire, google-api-python-client, google-auth, google-cloud-storage, jsonschema, kfp-pipeline-spec, kfp-server-api, kubernetes, protobuf, pydantic, PyYAML, requests-toolbelt, strip-hints, tabulate, typer, typing-extensions, uritemplate\n", + "Required-by: kubeflow-kale\n" + ] + } + ], + "source": [ + "# confirm the kfp sdk\n", + "! pip show kfp" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [ + "imports" + ] + }, + "outputs": [], + "source": [ + "import kfp\n", + "import kfp.components as comp\n", + "import kfp.dsl as dsl\n", + "from kfp.components import OutputPath\n", + "from typing import NamedTuple" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# Kubeflow pipeline component creation\n", + "\n", + "## Download the dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# load data step\n", + "def download_data(dataset, \n", + " data_path):\n", + " \n", + " # install the necessary libraries\n", + " import os, sys, subprocess, zipfile, pickle;\n", + " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','kaggle'])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','wget'])\n", + " \n", + " # import libraries\n", + " import pandas as pd\n", + " import wget\n", + "\n", + " # setup kaggle environment for data download\n", + " with open('/secret/kaggle-secret/password', 'r') as file:\n", + " kaggle_key = file.read().rstrip()\n", + " with open('/secret/kaggle-secret/username', 'r') as file:\n", + " kaggle_user = file.read().rstrip()\n", + " \n", + " os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", + " \n", + " # create data_path directory\n", + " if not os.path.exists(data_path):\n", + " os.makedirs(data_path)\n", + " \n", + " # download kaggle's Amex-credit-prediction data\n", + " subprocess.run([\"kaggle\",\"datasets\", \"download\", \"-d\", f'raddar/{dataset}'])\n", + " \n", + " # extract Amex-credit-prediction.zip to data_path\n", + " with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", + " zip_ref.extractall(data_path)\n", + "\n", + " # download kaggle's Amex-credit-prediction train_labels.zip\n", + " download_link = \"https://github.com/kubeflow/examples/blob/master/american-express-default-kaggle-competition/data/train_labels.zip?raw=true\"\n", + " \n", + " wget.download(download_link, f'{data_path}/train_labels.zip')\n", + "\n", + " # extract Amex-credit-prediction.zip to data_path\n", + " with zipfile.ZipFile(f'{data_path}/train_labels.zip','r') as zip_ref:\n", + " zip_ref.extractall(data_path)\n", + "\n", + " # delete zipfiles\n", + " subprocess.run(['rm', f'{dataset}.zip'])\n", + " subprocess.run(['rm', f'{data_path}/train_labels.zip'])\n", + " return(print('Done!'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Load Data" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# load data step\n", + "def load_data(data_path):\n", + " \n", + " # install the necessary libraries\n", + " import os, sys, subprocess, pickle;\n", + " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','pyarrow'])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','fastparquet'])\n", + " \n", + " # import libraries\n", + " import pandas as pd\n", + "\n", + " TRAIN_CSV = (f'{data_path}/train.parquet')\n", + " TEST_CSV = f'{data_path}/test.parquet'\n", + " TARGET_CSV = f'{data_path}/train_labels.csv'\n", + " \n", + " # read parquet TRAIN, TEST and TARGET_CSV\n", + " df_train = pd.read_parquet(TRAIN_CSV)\n", + " df_test = pd.read_parquet(TEST_CSV)\n", + " target = pd.read_csv(TARGET_CSV).target.values\n", + " print(f\"target shape: {target.shape}\")\n", + " \n", + " \n", + " # Save all data as a pickle file to be used by the feature_engineering component.\n", + " with open(f'{data_path}/df_data', 'wb') as f:\n", + " pickle.dump((df_train, target, df_test), f)\n", + " \n", + " return(print('Done!'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Feature Engineering" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# feature engineering step\n", + "\n", + "def feature_engineering(data_path):\n", + " \n", + " # install the necessary libraries\n", + " import sys, subprocess;\n", + " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", + " \n", + " # import Library\n", + " import os, pickle, gc\n", + " import numpy as np\n", + " import pandas as pd\n", + "\n", + " # loading data\n", + " with open(f'{data_path}/df_data', 'rb') as f:\n", + " df_train, target, df_test = pickle.load(f)\n", + " \n", + " # feature engineering gotten from https://www.kaggle.com/code/ambrosm/amex-lightgbm-quickstart\n", + " def get_features(df, \n", + " features_avg, \n", + " features_min, \n", + " features_max, \n", + " features_last\n", + " ):\n", + " '''\n", + " This function takes a dataframe with all features and returns the aggregated feature grouped by the customer id.\n", + "\n", + " df - dataframe\n", + " '''\n", + " cid = pd.Categorical(df.pop('customer_ID'), ordered=True) # get customer id\n", + " last = (cid != np.roll(cid, -1)) # mask for last statement of every customer\n", + "\n", + " df_avg = (df\n", + " .groupby(cid)\n", + " .mean()[features_avg]\n", + " .rename(columns={f: f\"{f}_avg\" for f in features_avg})\n", + " ) \n", + "\n", + " df_min = (df\n", + " .groupby(cid)\n", + " .min()[features_min]\n", + " .rename(columns={f: f\"{f}_min\" for f in features_min})\n", + " )\n", + " gc.collect()\n", + " print('Computed min')\n", + "\n", + " df_max = (df\n", + " .groupby(cid)\n", + " .max()[features_max]\n", + " .rename(columns={f: f\"{f}_max\" for f in features_max})\n", + " )\n", + " gc.collect()\n", + " print('Computed max')\n", + "\n", + " df = (df.loc[last, features_last]\n", + " .rename(columns={f: f\"{f}_last\" for f in features_last})\n", + " .set_index(np.asarray(cid[last]))\n", + " )\n", + " gc.collect()\n", + " print('Computed last')\n", + "\n", + " df_ = pd.concat([df, df_min, df_max, df_avg], axis=1, )\n", + "\n", + " del df, df_avg, df_min, df_max, cid, last\n", + "\n", + " return df_\n", + " \n", + " features_avg = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', \n", + " 'B_16', 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_28', 'B_29', 'B_30', \n", + " 'B_32', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', \n", + " 'D_45', 'D_46', 'D_47', 'D_48', 'D_50', 'D_51', 'D_53', 'D_54', 'D_55', 'D_58', 'D_59', 'D_60', 'D_61', \n", + " 'D_62', 'D_65', 'D_66', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_75', 'D_76', 'D_77', 'D_78', \n", + " 'D_80', 'D_82', 'D_84', 'D_86', 'D_91', 'D_92', 'D_94', 'D_96', 'D_103', 'D_104', 'D_108', 'D_112', 'D_113', \n", + " 'D_114', 'D_115', 'D_117', 'D_118', 'D_119', 'D_120', 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', \n", + " 'D_128', 'D_129', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', 'D_140', 'D_141', 'D_142', 'D_144', \n", + " 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_2', 'R_3', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_14', 'R_15', 'R_16', \n", + " 'R_17', 'R_20', 'R_21', 'R_22', 'R_24', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_9', 'S_11', 'S_12', 'S_13', \n", + " 'S_15', 'S_16', 'S_18', 'S_22', 'S_23', 'S_25', 'S_26']\n", + " features_min = ['B_2', 'B_4', 'B_5', 'B_9', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', 'B_19', 'B_20', 'B_28', 'B_29', 'B_33', 'B_36', \n", + " 'B_42', 'D_39', 'D_41', 'D_42', 'D_45', 'D_46', 'D_48', 'D_50', 'D_51', 'D_53', 'D_55', 'D_56', 'D_58', 'D_59', \n", + " 'D_60', 'D_62', 'D_70', 'D_71', 'D_74', 'D_75', 'D_78', 'D_83', 'D_102', 'D_112', 'D_113', 'D_115', 'D_118', 'D_119', \n", + " 'D_121', 'D_122', 'D_128', 'D_132', 'D_140', 'D_141', 'D_144', 'D_145', 'P_2', 'P_3', 'R_1', 'R_27', 'S_3', 'S_5', \n", + " 'S_7', 'S_9', 'S_11', 'S_12', 'S_23', 'S_25']\n", + " features_max = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', \n", + " 'B_18', 'B_19', 'B_21', 'B_23', 'B_24', 'B_25', 'B_29', 'B_30', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_42', 'D_39', \n", + " 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', 'D_48', 'D_49', 'D_50', 'D_52', 'D_55', 'D_56', 'D_58', 'D_59', \n", + " 'D_60', 'D_61', 'D_63', 'D_64', 'D_65', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_76', 'D_77', 'D_78', 'D_80', 'D_82', \n", + " 'D_84', 'D_91', 'D_102', 'D_105', 'D_107', 'D_110', 'D_111', 'D_112', 'D_115', 'D_116', 'D_117', 'D_118', 'D_119', \n", + " 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', 'D_128', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', \n", + " 'D_138', 'D_140', 'D_141', 'D_142', 'D_144', 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_3', 'R_5', 'R_6', 'R_7', 'R_8', \n", + " 'R_10', 'R_11', 'R_14', 'R_17', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_7', 'S_8', 'S_11', 'S_12', 'S_13', 'S_15', 'S_16', \n", + " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']\n", + " features_last = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', \n", + " 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_26', 'B_28', 'B_29', 'B_30', 'B_32', 'B_33', \n", + " 'B_36', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', \n", + " 'D_48', 'D_49', 'D_50', 'D_51', 'D_52', 'D_53', 'D_54', 'D_55', 'D_56', 'D_58', 'D_59', 'D_60', 'D_61', 'D_62', 'D_63', \n", + " 'D_64', 'D_65', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_75', 'D_76', 'D_77', 'D_78', 'D_79', 'D_80', 'D_81', 'D_82', \n", + " 'D_83', 'D_86', 'D_91', 'D_96', 'D_105', 'D_106', 'D_112', 'D_114', 'D_119', 'D_120', 'D_121', 'D_122', 'D_124', 'D_125', \n", + " 'D_126', 'D_127', 'D_130', 'D_131', 'D_132', 'D_133', 'D_134', 'D_138', 'D_140', 'D_141', 'D_142', 'D_145', 'P_2', 'P_3', \n", + " 'P_4', 'R_1', 'R_2', 'R_3', 'R_4', 'R_5', 'R_6', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_12', 'R_13', 'R_14', 'R_15', \n", + " 'R_19', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_8', 'S_9', 'S_11', 'S_12', 'S_13', 'S_16', 'S_19', 'S_20', \n", + " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']\n", + " \n", + " # apply feature engineering function\n", + " train = get_features(df_train, features_avg, features_min, features_max, features_last)\n", + " test = get_features(df_test, features_avg, features_min, features_max, features_last)\n", + "\n", + " # save the feature engineered data as a pickle file to be used by the modeling component.\n", + " with open(f'{data_path}/features_df', 'wb') as f:\n", + " pickle.dump((train, test, target), f)\n", + " \n", + " return(print('Done!')) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "papermill": { + "duration": 0.01421, + "end_time": "2022-04-17T07:17:13.396620", + "exception": false, + "start_time": "2022-04-17T07:17:13.382410", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "## Modelling\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# modeling step\n", + "\n", + "def modeling(data_path):\n", + " \n", + " # install the necessary libraries\n", + " import sys, subprocess;\n", + " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','pandas'])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','scikit-learn'])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','lightgbm'])\n", + " \n", + " # import Library\n", + " import os, pickle, joblib, warnings;\n", + " import pandas as pd\n", + " import numpy as np\n", + " from sklearn.model_selection import StratifiedKFold\n", + " from lightgbm import LGBMClassifier\n", + " warnings.filterwarnings(\"ignore\")\n", + " \n", + " # loading data\n", + " with open(f'{data_path}/features_df', 'rb') as f:\n", + " train, test, target = pickle.load(f)\n", + " \n", + " # define the evaluation metric\n", + " # From https://www.kaggle.com/competitions/amex-default-prediction/discussion/328020\n", + " def amex_metric(y_true: np.array, y_pred: np.array) -> float:\n", + "\n", + " # count of positives and negatives\n", + " n_pos = y_true.sum()\n", + " n_neg = y_true.shape[0] - n_pos\n", + "\n", + " # sorting by descring prediction values\n", + " indices = np.argsort(y_pred)[::-1]\n", + " preds, target = y_pred[indices], y_true[indices]\n", + "\n", + " # filter the top 4% by cumulative row weights\n", + " weight = 20.0 - target * 19.0\n", + " cum_norm_weight = (weight / weight.sum()).cumsum()\n", + " four_pct_filter = cum_norm_weight <= 0.04\n", + "\n", + " # default rate captured at 4%\n", + " d = target[four_pct_filter].sum() / n_pos\n", + "\n", + " # weighted gini coefficient\n", + " lorentz = (target / n_pos).cumsum()\n", + " gini = ((lorentz - cum_norm_weight) * weight).sum()\n", + "\n", + " # max weighted gini coefficient\n", + " gini_max = 10 * n_neg * (1 - 19 / (n_pos + 20 * n_neg))\n", + "\n", + " # normalized weighted gini coefficient\n", + " g = gini / gini_max\n", + "\n", + " return 0.5 * (g + d)\n", + "\n", + " def lgb_amex_metric(y_true, y_pred):\n", + " \"\"\"The competition metric with lightgbm's calling convention\"\"\"\n", + " return ('amex_metric_score',\n", + " amex_metric(y_true, y_pred),\n", + " True)\n", + " \n", + " # Cross-validation\n", + "\n", + " features = [f for f in train.columns if f != 'customer_ID' and f != 'target']\n", + "\n", + " print(f\"{len(features)} features\")\n", + "\n", + " score_list = [] # lgbm score per fold\n", + " y_pred_list = [] # fold predictions list\n", + "\n", + " # init StratifiedKFold\n", + " kf = StratifiedKFold(n_splits=4)\n", + "\n", + " for fold, (idx_tr, idx_va) in enumerate(kf.split(train, target)):\n", + "\n", + " X_tr, X_va, y_tr, y_va, model = None, None, None, None, None\n", + "\n", + " X_tr = train.iloc[idx_tr][features]\n", + " X_va = train.iloc[idx_va][features]\n", + " y_tr = target[idx_tr]\n", + " y_va = target[idx_va]\n", + "\n", + " # init model\n", + " model = LGBMClassifier(n_estimators=30,\n", + " learning_rate=0.1, \n", + " num_leaves=100,\n", + " random_state=2022)\n", + " # fit model\n", + " model.fit(X_tr, y_tr,\n", + " eval_set = [(X_va, y_va)], \n", + " eval_metric=[lgb_amex_metric],\n", + " verbose = 20,\n", + " early_stopping_rounds=30)\n", + "\n", + " X_tr, y_tr = None, None\n", + "\n", + " # fold validation set predictions\n", + " y_va_pred = model.predict_proba(X_va, raw_score=True)\n", + "\n", + " # model score\n", + " score = amex_metric(y_va, y_va_pred)\n", + "\n", + " print(f\"Score = {score}\")\n", + " score_list.append(score)\n", + "\n", + " # test set predictions\n", + " y_pred_list.append(model.predict_proba(test[features], raw_score=True))\n", + "\n", + " print(f\"Fold {fold}\") \n", + "\n", + " # save model\n", + " joblib.dump(model, f'{data_path}/lgb.jl')\n", + " \n", + " return(print('Done!')) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "papermill": { + "duration": 0.01428, + "end_time": "2022-04-17T07:17:23.959655", + "exception": false, + "start_time": "2022-04-17T07:17:23.945375", + "status": "completed" + }, + "tags": [] + }, + "source": [ + "## Evaluation" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# evaluation step\n", + "\n", + "def evaluation_result(data_path, \n", + " metrics_path: OutputPath(str)) -> NamedTuple(\"EvaluationOutput\", [(\"mlpipeline_metrics\", \"Metrics\")]):\n", + " \n", + " # import Library\n", + " import sys, subprocess;\n", + " subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"])\n", + " subprocess.run([sys.executable, '-m', 'pip', 'install','lightgbm'])\n", + " import json;\n", + " from collections import namedtuple\n", + " import joblib\n", + " import lightgbm as lgb\n", + " from lightgbm import LGBMRegressor\n", + " \n", + " # load model\n", + " model = joblib.load(f'{data_path}/lgb.jl')\n", + "\n", + " # model evaluation\n", + " binary_logloss = model.booster_.best_score.get('valid_0').get('binary_logloss')\n", + " amex_metric_score = model.booster_.best_score.get('valid_0').get('amex_metric_score')\n", + " \n", + " # create kubeflow metric metadata for UI \n", + " metrics = {\n", + " 'metrics': [\n", + " {'name': 'binary-logloss',\n", + " 'numberValue': binary_logloss,\n", + " 'format': 'RAW'},\n", + " {'name': 'amex-metric-score',\n", + " 'numberValue': amex_metric_score,\n", + " 'format': 'RAW'}\n", + " ]\n", + " }\n", + " \n", + "\n", + " with open(metrics_path, \"w\") as f:\n", + " json.dump(metrics, f)\n", + "\n", + " output_tuple = namedtuple(\"EvaluationOutput\", [\"mlpipeline_metrics\"])\n", + "\n", + " return output_tuple(json.dumps(metrics))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create pipeline components \n", + "\n", + "using `create_component_from_func`" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# create light weight components\n", + "download_op = comp.create_component_from_func(download_data,base_image=\"python:3.7.1\")\n", + "load_op = comp.create_component_from_func(load_data,base_image=\"python:3.7.1\")\n", + "feature_eng_op = comp.create_component_from_func(feature_engineering,base_image=\"python:3.7.1\")\n", + "modeling_op = comp.create_component_from_func(modeling, base_image=\"python:3.7.1\")\n", + "evaluation_op = comp.create_component_from_func(evaluation_result, base_image=\"python:3.7.1\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Kubeflow pipeline creation" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# define pipeline\n", + "@dsl.pipeline(name=\"american-express-default-prediction-pipeline\", \n", + " description=\"predicting credit default.\")\n", + "\n", + "# Define parameters to be fed into pipeline\n", + "def american_express_default_prediction_pipeline(\n", + " dataset: str,\n", + " data_path: str\n", + " ):\n", + " # Define volume to share data between components.\n", + " vop = dsl.VolumeOp(\n", + " name=\"create_data_volume\",\n", + " resource_name=\"data-volume\", \n", + " size=\"24Gi\", \n", + " modes=dsl.VOLUME_MODE_RWO)\n", + " \n", + " \n", + " # Create download container.\n", + " download_container = download_op(dataset, data_path)\\\n", + " .add_pvolumes({data_path: vop.volume}).add_pod_label(\"kaggle-secret\", \"true\")\n", + " # Create load container.\n", + " load_container = load_op(data_path)\\\n", + " .add_pvolumes({data_path: download_container.pvolume})\n", + " # Create feature engineering container.\n", + " feat_eng_container = feature_eng_op(data_path)\\\n", + " .add_pvolumes({data_path: load_container.pvolume})\n", + " # Create modeling container.\n", + " modeling_container = modeling_op(data_path)\\\n", + " .add_pvolumes({data_path: feat_eng_container.pvolume})\n", + " # Create prediction container.\n", + " evaluation_container = evaluation_op(data_path).add_pvolumes({data_path: modeling_container.pvolume})" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# create client that would enable communication with the Pipelines API server \n", + "client = kfp.Client()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# arguments\n", + "dataset = \"amex-data-integer-dtypes-parquet-format\"\n", + "data_path = \"/mnt\"" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Experiment details." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "Run details." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "pipeline_func = american_express_default_prediction_pipeline\n", + "\n", + "experiment_name = 'american_express_default_prediction_pipeline_lightweight'\n", + "run_name = pipeline_func.__name__ + ' run'\n", + "\n", + "arguments = {\n", + " \"dataset\": dataset,\n", + " \"data_path\": data_path\n", + " }\n", + "\n", + "# Compile pipeline to generate compressed YAML definition of the pipeline.\n", + "kfp.compiler.Compiler().compile(pipeline_func, \n", + " '{}.zip'.format(experiment_name))\n", + "\n", + "# Submit pipeline directly from pipeline function\n", + "run_result = client.create_run_from_pipeline_func(pipeline_func, \n", + " experiment_name=experiment_name, \n", + " run_name=run_name, \n", + " arguments=arguments\n", + " )\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "kubeflow_notebook": { + "autosnapshot": true, + "experiment": { + "id": "2efb8e27-3b2e-439b-a53c-b1f9d7b94cfc", + "name": "g-research-crypto-forecasting" + }, + "experiment_name": "g-research-crypto-forecasting", + "katib_metadata": { + "algorithm": { + "algorithmName": "grid" + }, + "maxFailedTrialCount": 3, + "maxTrialCount": 12, + "objective": { + "objectiveMetricName": "", + "type": "minimize" + }, + "parallelTrialCount": 3, + "parameters": [] + }, + "katib_run": false, + "pipeline_description": "Forecasting short term returns in 14 popular cryptocurrencies.", + "pipeline_name": "g-research-crypto-forecasting-pipeline", + "snapshot_volumes": true, + "steps_defaults": [ + "label:access-ml-pipeline:true", + "label:kaggle-secret:true", + "label:access-rok:true" + ], + "volume_access_mode": "rwm", + "volumes": [ + { + "annotations": [], + "mount_point": "/home/jovyan", + "name": "test-workspace-qtvmt", + "size": 32, + "size_type": "Gi", + "snapshot": false, + "type": "clone" + } + ] + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.9" + }, + "papermill": { + "default_parameters": {}, + "duration": 32.012084, + "end_time": "2022-04-17T07:17:25.053666", + "environment_variables": {}, + "exception": null, + "input_path": "__notebook__.ipynb", + "output_path": "__notebook__.ipynb", + "parameters": {}, + "start_time": "2022-04-17T07:16:53.041582", + "version": "2.3.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/american-express-default-kaggle-competition/american-express-default-prediction-orig.ipynb b/american-express-default-kaggle-competition/american-express-default-prediction-orig.ipynb index 9c73415b0..31f93f1dd 100644 --- a/american-express-default-kaggle-competition/american-express-default-prediction-orig.ipynb +++ b/american-express-default-kaggle-competition/american-express-default-prediction-orig.ipynb @@ -1,872 +1,872 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "# 🪙 American Express - Default Prediction Competition Original Notebook\n", - "![](./images/background.jpg)\n", - "\n", - "---\n", - "\n", - "In this [Kaggle competition](https://www.kaggle.com/competitions/g-research-crypto-forecasting/overview), you'll use your machine learning expertise to predict credit default. This competition is hosted by American Express. \n", - "\n", - "> American Express is a globally integrated payments company. The largest payment card issuer in the world, they provide customers with access to products, insights, and experiences that enrich lives and build business success.\n", - "\n", - "The dataset provided is an industrial scale data set of about 5.5 million rows. It has been pre-processed and converted to a lightweight version by raddar for ease of training and better result. This dataset is available in a [parquet format][1].\n", - "\n", - "[1]: https://www.kaggle.com/datasets/raddar/amex-data-integer-dtypes-parquet-format" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Install necessary packages\n", - "\n", - "We can install the necessary package by either running pip install --user or include everything in a requirements.txt file and run pip install --user -r requirements.txt. We have put the dependencies in a requirements.txt file so we will use the former method.\n", - "\n", - "NOTE: After installing python packages, restart notebook kernel before proceeding." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "!pip install -r requirements.txt --user --quiet" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Imports\n", - "\n", - "In this section we import the packages we need for this example. Make it a habit to gather your imports in a single place. It will make your life easier if you are going to transform this notebook into a Kubeflow pipeline using Kale." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "tags": [ - "imports" - ] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pandas as pd\n", - "import os, subprocess\n", - "import random, zipfile, joblib\n", - "import scipy.stats\n", - "import warnings\n", - "import gc, wget\n", - "\n", - "from sklearn.model_selection import StratifiedKFold\n", - "from lightgbm import LGBMClassifier, log_evaluation\n", - "\n", - "warnings.filterwarnings(\"ignore\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Project hyper-parameters\n", - "\n", - "In this cell, we define the different hyper-parameters. Defining them in one place makes it easier to experiment with their values and also facilitates the execution of HP Tuning experiments using Kale and Katib." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "tags": [ - "pipeline-parameters" - ] - }, - "outputs": [], - "source": [ - "# Hyper-parameters\n", - "N_EST = 30\n", - "LR = 0.1" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "Set random seed for reproducibility" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "def fix_all_seeds(seed):\n", - " np.random.seed(seed)\n", - " random.seed(seed)\n", - " os.environ['PYTHONHASHSEED'] = str(seed)\n", - "\n", - "fix_all_seeds(2022)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Download data\n", - "\n", - "In this section, we download the data from kaggle using the Kaggle API credentials" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "tags": [ - "block:download_data" - ] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "CompletedProcess(args=['kaggle', 'datasets', 'download', '-d', 'raddar/amex-data-integer-dtypes-parquet-format'], returncode=0)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# setup kaggle environment for data download\n", - "dataset = \"amex-data-integer-dtypes-parquet-format\"\n", - "\n", - "# setup kaggle environment for data download\n", - "with open('/secret/kaggle-secret/password', 'r') as file:\n", - " kaggle_key = file.read().rstrip()\n", - "with open('/secret/kaggle-secret/username', 'r') as file:\n", - " kaggle_user = file.read().rstrip()\n", - "\n", - "os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", - "\n", - "# download kaggle's Amex-credit-prediction data\n", - "subprocess.run([\"kaggle\",\"datasets\", \"download\", \"-d\", f'raddar/{dataset}'])" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "tags": [ - "block:" - ] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "CompletedProcess(args=['rm', 'data/train_labels.zip'], returncode=0)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# path to download to\n", - "data_path = 'data'\n", - "\n", - "# extract Amex-credit-prediction.zip to data_path\n", - "with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", - " zip_ref.extractall(data_path)\n", - " \n", - "# download kaggle's Amex-credit-prediction train_labels.zip\n", - "download_link = \"https://github.com/kubeflow/examples/blob/master/american-express-default-kaggle-competition/data/train_labels.zip?raw=true\"\n", - "wget.download(download_link, f'{data_path}/train_labels.zip')\n", - "\n", - "# extract Amex-credit-prediction.zip to data_path\n", - "with zipfile.ZipFile(f'{data_path}/train_labels.zip','r') as zip_ref:\n", - " zip_ref.extractall(data_path)\n", - " \n", - "# delete zipfiles\n", - "subprocess.run(['rm', f'{dataset}.zip'])\n", - "subprocess.run(['rm', f'{data_path}/train_labels.zip'])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Load the dataset\n", - "\n", - "First, let us load and analyze the data.\n", - "\n", - "The data is in csv format, thus, we use the handy read_csv pandas method." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "tags": [ - "block:load_data", - "prev:download_data" - ] - }, - "outputs": [], - "source": [ - "TRAIN_CSV = (f'{data_path}/train.parquet')\n", - "TEST_CSV = f'{data_path}/test.parquet'\n", - "TARGET_CSV = f'{data_path}/train_labels.csv'" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "target shape: (458913,)\n" - ] - } - ], - "source": [ - "df_train = pd.read_parquet(TRAIN_CSV)\n", - "df_test = pd.read_parquet(TEST_CSV)\n", - "target = pd.read_csv(TARGET_CSV).target.values\n", - "print(f\"target shape: {target.shape}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(5531451, 190)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "customer_ID 0\n", - "S_2 0\n", - "P_2 45985\n", - "D_39 0\n", - "B_1 0\n", - " ... \n", - "D_141 101548\n", - "D_142 4587043\n", - "D_143 0\n", - "D_144 40727\n", - "D_145 0\n", - "Length: 190, dtype: int64" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_train.isna().sum()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "### Define Helper Functions" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "tags": [ - "functions" - ] - }, - "outputs": [], - "source": [ - "# @yunchonggan's fast metric implementation\n", - "# From https://www.kaggle.com/competitions/amex-default-prediction/discussion/328020\n", - "def amex_metric(y_true: np.array, y_pred: np.array) -> float:\n", - "\n", - " # count of positives and negatives\n", - " n_pos = y_true.sum()\n", - " n_neg = y_true.shape[0] - n_pos\n", - "\n", - " # sorting by descring prediction values\n", - " indices = np.argsort(y_pred)[::-1]\n", - " preds, target = y_pred[indices], y_true[indices]\n", - "\n", - " # filter the top 4% by cumulative row weights\n", - " weight = 20.0 - target * 19.0\n", - " cum_norm_weight = (weight / weight.sum()).cumsum()\n", - " four_pct_filter = cum_norm_weight <= 0.04\n", - "\n", - " # default rate captured at 4%\n", - " d = target[four_pct_filter].sum() / n_pos\n", - "\n", - " # weighted gini coefficient\n", - " lorentz = (target / n_pos).cumsum()\n", - " gini = ((lorentz - cum_norm_weight) * weight).sum()\n", - "\n", - " # max weighted gini coefficient\n", - " gini_max = 10 * n_neg * (1 - 19 / (n_pos + 20 * n_neg))\n", - "\n", - " # normalized weighted gini coefficient\n", - " g = gini / gini_max\n", - "\n", - " return 0.5 * (g + d)\n", - "\n", - "def lgb_amex_metric(y_true, y_pred):\n", - " \"\"\"The competition metric with lightgbm's calling convention\"\"\"\n", - " return ('amex_metric_score',\n", - " amex_metric(y_true, y_pred),\n", - " True)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Feature Engineering" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "features_avg = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', \n", - " 'B_16', 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_28', 'B_29', 'B_30', \n", - " 'B_32', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', \n", - " 'D_45', 'D_46', 'D_47', 'D_48', 'D_50', 'D_51', 'D_53', 'D_54', 'D_55', 'D_58', 'D_59', 'D_60', 'D_61', \n", - " 'D_62', 'D_65', 'D_66', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_75', 'D_76', 'D_77', 'D_78', \n", - " 'D_80', 'D_82', 'D_84', 'D_86', 'D_91', 'D_92', 'D_94', 'D_96', 'D_103', 'D_104', 'D_108', 'D_112', 'D_113', \n", - " 'D_114', 'D_115', 'D_117', 'D_118', 'D_119', 'D_120', 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', \n", - " 'D_128', 'D_129', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', 'D_140', 'D_141', 'D_142', 'D_144', \n", - " 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_2', 'R_3', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_14', 'R_15', 'R_16', \n", - " 'R_17', 'R_20', 'R_21', 'R_22', 'R_24', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_9', 'S_11', 'S_12', 'S_13', \n", - " 'S_15', 'S_16', 'S_18', 'S_22', 'S_23', 'S_25', 'S_26']\n", - "features_min = ['B_2', 'B_4', 'B_5', 'B_9', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', 'B_19', 'B_20', 'B_28', 'B_29', 'B_33', 'B_36', \n", - " 'B_42', 'D_39', 'D_41', 'D_42', 'D_45', 'D_46', 'D_48', 'D_50', 'D_51', 'D_53', 'D_55', 'D_56', 'D_58', 'D_59', \n", - " 'D_60', 'D_62', 'D_70', 'D_71', 'D_74', 'D_75', 'D_78', 'D_83', 'D_102', 'D_112', 'D_113', 'D_115', 'D_118', 'D_119', \n", - " 'D_121', 'D_122', 'D_128', 'D_132', 'D_140', 'D_141', 'D_144', 'D_145', 'P_2', 'P_3', 'R_1', 'R_27', 'S_3', 'S_5', \n", - " 'S_7', 'S_9', 'S_11', 'S_12', 'S_23', 'S_25']\n", - "features_max = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', \n", - " 'B_18', 'B_19', 'B_21', 'B_23', 'B_24', 'B_25', 'B_29', 'B_30', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_42', 'D_39', \n", - " 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', 'D_48', 'D_49', 'D_50', 'D_52', 'D_55', 'D_56', 'D_58', 'D_59', \n", - " 'D_60', 'D_61', 'D_63', 'D_64', 'D_65', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_76', 'D_77', 'D_78', 'D_80', 'D_82', \n", - " 'D_84', 'D_91', 'D_102', 'D_105', 'D_107', 'D_110', 'D_111', 'D_112', 'D_115', 'D_116', 'D_117', 'D_118', 'D_119', \n", - " 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', 'D_128', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', \n", - " 'D_138', 'D_140', 'D_141', 'D_142', 'D_144', 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_3', 'R_5', 'R_6', 'R_7', 'R_8', \n", - " 'R_10', 'R_11', 'R_14', 'R_17', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_7', 'S_8', 'S_11', 'S_12', 'S_13', 'S_15', 'S_16', \n", - " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']\n", - "features_last = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', \n", - " 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_26', 'B_28', 'B_29', 'B_30', 'B_32', 'B_33', \n", - " 'B_36', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', \n", - " 'D_48', 'D_49', 'D_50', 'D_51', 'D_52', 'D_53', 'D_54', 'D_55', 'D_56', 'D_58', 'D_59', 'D_60', 'D_61', 'D_62', 'D_63', \n", - " 'D_64', 'D_65', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_75', 'D_76', 'D_77', 'D_78', 'D_79', 'D_80', 'D_81', 'D_82', \n", - " 'D_83', 'D_86', 'D_91', 'D_96', 'D_105', 'D_106', 'D_112', 'D_114', 'D_119', 'D_120', 'D_121', 'D_122', 'D_124', 'D_125', \n", - " 'D_126', 'D_127', 'D_130', 'D_131', 'D_132', 'D_133', 'D_134', 'D_138', 'D_140', 'D_141', 'D_142', 'D_145', 'P_2', 'P_3', \n", - " 'P_4', 'R_1', 'R_2', 'R_3', 'R_4', 'R_5', 'R_6', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_12', 'R_13', 'R_14', 'R_15', \n", - " 'R_19', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_8', 'S_9', 'S_11', 'S_12', 'S_13', 'S_16', 'S_19', 'S_20', \n", - " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "tags": [ - "block:feature_engineering", - "prev:load_data" - ] - }, - "outputs": [], - "source": [ - "# feature engineering gotten from https://www.kaggle.com/code/ambrosm/amex-lightgbm-quickstart\n", - "def get_features(df, \n", - " features_avg, \n", - " features_min, \n", - " features_max, \n", - " features_last\n", - " ):\n", - " '''\n", - " This function takes a dataframe with all features and returns the aggregated feature grouped by the customer id.\n", - " \n", - " df - dataframe\n", - " '''\n", - " cid = pd.Categorical(df.pop('customer_ID'), ordered=True) # get customer id\n", - " last = (cid != np.roll(cid, -1)) # mask for last statement of every customer\n", - " \n", - " df_avg = (df\n", - " .groupby(cid)\n", - " .mean()[features_avg]\n", - " .rename(columns={f: f\"{f}_avg\" for f in features_avg})\n", - " ) \n", - " \n", - " df_min = (df\n", - " .groupby(cid)\n", - " .min()[features_min]\n", - " .rename(columns={f: f\"{f}_min\" for f in features_min})\n", - " )\n", - " gc.collect()\n", - " print('Computed min')\n", - " \n", - " df_max = (df\n", - " .groupby(cid)\n", - " .max()[features_max]\n", - " .rename(columns={f: f\"{f}_max\" for f in features_max})\n", - " )\n", - " gc.collect()\n", - " print('Computed max')\n", - " \n", - " df = (df.loc[last, features_last]\n", - " .rename(columns={f: f\"{f}_last\" for f in features_last})\n", - " .set_index(np.asarray(cid[last]))\n", - " )\n", - " gc.collect()\n", - " print('Computed last')\n", - " \n", - " df_ = pd.concat([df, df_min, df_max, df_avg], axis=1, )\n", - " \n", - " del df, df_avg, df_min, df_max, cid, last\n", - " \n", - " return df_" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Computed min\n", - "Computed max\n", - "Computed last\n", - "Computed min\n", - "Computed max\n", - "Computed last\n" - ] - } - ], - "source": [ - "# apply feature engineering function\n", - "train = get_features(df_train, features_avg, features_min, features_max, features_last)\n", - "test = get_features(df_test, features_avg, features_min, features_max, features_last)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "B_1_last False\n", - "B_2_last True\n", - "B_3_last True\n", - "B_4_last False\n", - "B_5_last False\n", - " ... \n", - "S_18_avg False\n", - "S_22_avg True\n", - "S_23_avg True\n", - "S_25_avg True\n", - "S_26_avg False\n", - "Length: 469, dtype: bool" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# check null values\n", - "train.isna().any()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Modelling: StratifiedKFold\n", - "\n", - "We cross-validate with a six-fold StratifiedKFold to handle the imbalanced nature of the target.\n", - "\n", - "Lightgbm handles null values efficiently." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "tags": [ - "block:modelling", - "prev:feature_engineering" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "469 features\n", - "[20]\tvalid_0's binary_logloss: 0.267976\tvalid_0's amex_metric_score: 0.750976\n", - "Score = 0.7604229987279087\n", - "Fold 0\n", - "[20]\tvalid_0's binary_logloss: 0.267339\tvalid_0's amex_metric_score: 0.753257\n", - "Score = 0.7624180573803372\n", - "Fold 1\n", - "OOF Score: 0.76142\n" - ] - } - ], - "source": [ - "# Cross-validation\n", - "\n", - "features = [f for f in train.columns if f != 'customer_ID' and f != 'target']\n", - "\n", - "print(f\"{len(features)} features\")\n", - "\n", - "score_list = [] # lgbm score per fold\n", - "y_pred_list = [] # fold predictions list\n", - "\n", - "# init StratifiedKFold\n", - "kf = StratifiedKFold(n_splits=4)\n", - "\n", - "for fold, (idx_tr, idx_va) in enumerate(kf.split(train, target)):\n", - " \n", - " X_tr, X_va, y_tr, y_va, model = None, None, None, None, None\n", - "\n", - " X_tr = train.iloc[idx_tr][features]\n", - " X_va = train.iloc[idx_va][features]\n", - " y_tr = target[idx_tr]\n", - " y_va = target[idx_va]\n", - " \n", - " # init model\n", - " model = LGBMClassifier(n_estimators=N_EST,\n", - " learning_rate=LR, \n", - " random_state=2022)\n", - " # fit model\n", - " model.fit(X_tr, y_tr,\n", - " eval_set = [(X_va, y_va)], \n", - " eval_metric=[lgb_amex_metric],\n", - " early_stopping_rounds=30,\n", - " callbacks=[log_evaluation(20)])\n", - " \n", - " X_tr, y_tr = None, None\n", - " \n", - " # fold validation set predictions\n", - " y_va_pred = model.predict_proba(X_va, raw_score=True)\n", - " \n", - " # model score\n", - " score = amex_metric(y_va, y_va_pred)\n", - "\n", - " print(f\"Score = {score}\")\n", - " score_list.append(score)\n", - " \n", - " # test set predictions\n", - " y_pred_list.append(model.predict_proba(test[features], raw_score=True))\n", - " \n", - " print(f\"Fold {fold}\") \n", - "\n", - "# save model\n", - "joblib.dump(model, 'lgb.jl')\n", - "print(f\"OOF Score: {np.mean(score_list):.5f}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "

" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "# feature importance for top 30 features\n", - "fea_imp = pd.DataFrame({'imp':model.feature_importances_, 'col': features})\n", - "fea_imp = fea_imp.sort_values(['imp', 'col'], ascending=[True, False]).iloc[-30:]\n", - "_ = fea_imp.plot(kind='barh', x='col', y='imp', figsize=(20, 10))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Evaluation" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "tags": [ - "block:evaluation_result", - "prev:modelling" - ] - }, - "outputs": [], - "source": [ - "model = joblib.load('lgb.jl')" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "binary_logloss = model.booster_.best_score.get('valid_0').get('binary_logloss')" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "amex_metric_score = model.booster_.best_score.get('valid_0').get('amex_metric_score')" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "tags": [ - "pipeline-metrics" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.24605493989573005\n" - ] - } - ], - "source": [ - "print(binary_logloss)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "tags": [ - "pipeline-metrics" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.7625788091718922\n" - ] - } - ], - "source": [ - "print(amex_metric_score)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Submission" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "sub = pd.DataFrame({'customer_ID': test.index,\n", - " 'prediction': np.mean(y_pred_list, axis=0)})\n", - "sub.to_csv('submission.csv', index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "skip" - ] - }, - "outputs": [], - "source": [ - "sub" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kubeflow_notebook": { - "autosnapshot": true, - "experiment": { - "id": "2efb8e27-3b2e-439b-a53c-b1f9d7b94cfc", - "name": "g-research-crypto-forecasting" - }, - "experiment_name": "g-research-crypto-forecasting", - "katib_metadata": { - "algorithm": { - "algorithmName": "grid" - }, - "maxFailedTrialCount": 3, - "maxTrialCount": 12, - "objective": { - "objectiveMetricName": "", - "type": "minimize" - }, - "parallelTrialCount": 3, - "parameters": [] - }, - "katib_run": false, - "pipeline_description": "forecasting short term returns in 14 popular cryptocurrencies.", - "pipeline_name": "g-research-crypto-forecasting-pipeline", - "snapshot_volumes": true, - "steps_defaults": [ - "label:access-ml-pipeline:true", - "label:kaggle-secret:true", - "label:access-rok:true" - ], - "volume_access_mode": "rwm", - "volumes": [ - { - "annotations": [], - "mount_point": "/home/jovyan", - "name": "test-workspace-qtvmt", - "size": 32, - "size_type": "Gi", - "snapshot": false, - "type": "clone" - } - ] - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.9" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# 🪙 American Express - Default Prediction Competition Original Notebook\n", + "![](./images/background.jpg)\n", + "\n", + "---\n", + "\n", + "In this [Kaggle competition](https://www.kaggle.com/competitions/g-research-crypto-forecasting/overview), you'll use your machine learning expertise to predict credit default. This competition is hosted by American Express. \n", + "\n", + "> American Express is a globally integrated payments company. The largest payment card issuer in the world, they provide customers with access to products, insights, and experiences that enrich lives and build business success.\n", + "\n", + "The dataset provided is an industrial scale data set of about 5.5 million rows. It has been pre-processed and converted to a lightweight version by raddar for ease of training and better result. This dataset is available in a [parquet format][1].\n", + "\n", + "[1]: https://www.kaggle.com/datasets/raddar/amex-data-integer-dtypes-parquet-format" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Install necessary packages\n", + "\n", + "We can install the necessary package by either running pip install --user or include everything in a requirements.txt file and run pip install --user -r requirements.txt. We have put the dependencies in a requirements.txt file so we will use the former method.\n", + "\n", + "NOTE: After installing python packages, restart notebook kernel before proceeding." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "!pip install -r requirements.txt --user --quiet" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Imports\n", + "\n", + "In this section we import the packages we need for this example. Make it a habit to gather your imports in a single place. It will make your life easier if you are going to transform this notebook into a Kubeflow pipeline using Kale." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "tags": [ + "imports" + ] + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import os, subprocess\n", + "import random, zipfile, joblib\n", + "import scipy.stats\n", + "import warnings\n", + "import gc, wget\n", + "\n", + "from sklearn.model_selection import StratifiedKFold\n", + "from lightgbm import LGBMClassifier, log_evaluation\n", + "\n", + "warnings.filterwarnings(\"ignore\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Project hyper-parameters\n", + "\n", + "In this cell, we define the different hyper-parameters. Defining them in one place makes it easier to experiment with their values and also facilitates the execution of HP Tuning experiments using Kale and Katib." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "pipeline-parameters" + ] + }, + "outputs": [], + "source": [ + "# Hyper-parameters\n", + "N_EST = 30\n", + "LR = 0.1" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "Set random seed for reproducibility" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "def fix_all_seeds(seed):\n", + " np.random.seed(seed)\n", + " random.seed(seed)\n", + " os.environ['PYTHONHASHSEED'] = str(seed)\n", + "\n", + "fix_all_seeds(2022)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Download data\n", + "\n", + "In this section, we download the data from kaggle using the Kaggle API credentials" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [ + "block:download_data" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "CompletedProcess(args=['kaggle', 'datasets', 'download', '-d', 'raddar/amex-data-integer-dtypes-parquet-format'], returncode=0)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# setup kaggle environment for data download\n", + "dataset = \"amex-data-integer-dtypes-parquet-format\"\n", + "\n", + "# setup kaggle environment for data download\n", + "with open('/secret/kaggle-secret/password', 'r') as file:\n", + " kaggle_key = file.read().rstrip()\n", + "with open('/secret/kaggle-secret/username', 'r') as file:\n", + " kaggle_user = file.read().rstrip()\n", + "\n", + "os.environ['KAGGLE_USERNAME'], os.environ['KAGGLE_KEY'] = kaggle_user, kaggle_key\n", + "\n", + "# download kaggle's Amex-credit-prediction data\n", + "subprocess.run([\"kaggle\",\"datasets\", \"download\", \"-d\", f'raddar/{dataset}'])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [ + "block:" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "CompletedProcess(args=['rm', 'data/train_labels.zip'], returncode=0)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# path to download to\n", + "data_path = 'data'\n", + "\n", + "# extract Amex-credit-prediction.zip to data_path\n", + "with zipfile.ZipFile(f\"{dataset}.zip\",\"r\") as zip_ref:\n", + " zip_ref.extractall(data_path)\n", + " \n", + "# download kaggle's Amex-credit-prediction train_labels.zip\n", + "download_link = \"https://github.com/kubeflow/examples/blob/master/american-express-default-kaggle-competition/data/train_labels.zip?raw=true\"\n", + "wget.download(download_link, f'{data_path}/train_labels.zip')\n", + "\n", + "# extract Amex-credit-prediction.zip to data_path\n", + "with zipfile.ZipFile(f'{data_path}/train_labels.zip','r') as zip_ref:\n", + " zip_ref.extractall(data_path)\n", + " \n", + "# delete zipfiles\n", + "subprocess.run(['rm', f'{dataset}.zip'])\n", + "subprocess.run(['rm', f'{data_path}/train_labels.zip'])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Load the dataset\n", + "\n", + "First, let us load and analyze the data.\n", + "\n", + "The data is in csv format, thus, we use the handy read_csv pandas method." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "block:load_data", + "prev:download_data" + ] + }, + "outputs": [], + "source": [ + "TRAIN_CSV = (f'{data_path}/train.parquet')\n", + "TEST_CSV = f'{data_path}/test.parquet'\n", + "TARGET_CSV = f'{data_path}/train_labels.csv'" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "target shape: (458913,)\n" + ] + } + ], + "source": [ + "df_train = pd.read_parquet(TRAIN_CSV)\n", + "df_test = pd.read_parquet(TEST_CSV)\n", + "target = pd.read_csv(TARGET_CSV).target.values\n", + "print(f\"target shape: {target.shape}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(5531451, 190)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "customer_ID 0\n", + "S_2 0\n", + "P_2 45985\n", + "D_39 0\n", + "B_1 0\n", + " ... \n", + "D_141 101548\n", + "D_142 4587043\n", + "D_143 0\n", + "D_144 40727\n", + "D_145 0\n", + "Length: 190, dtype: int64" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train.isna().sum()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "### Define Helper Functions" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "tags": [ + "functions" + ] + }, + "outputs": [], + "source": [ + "# @yunchonggan's fast metric implementation\n", + "# From https://www.kaggle.com/competitions/amex-default-prediction/discussion/328020\n", + "def amex_metric(y_true: np.array, y_pred: np.array) -> float:\n", + "\n", + " # count of positives and negatives\n", + " n_pos = y_true.sum()\n", + " n_neg = y_true.shape[0] - n_pos\n", + "\n", + " # sorting by descring prediction values\n", + " indices = np.argsort(y_pred)[::-1]\n", + " preds, target = y_pred[indices], y_true[indices]\n", + "\n", + " # filter the top 4% by cumulative row weights\n", + " weight = 20.0 - target * 19.0\n", + " cum_norm_weight = (weight / weight.sum()).cumsum()\n", + " four_pct_filter = cum_norm_weight <= 0.04\n", + "\n", + " # default rate captured at 4%\n", + " d = target[four_pct_filter].sum() / n_pos\n", + "\n", + " # weighted gini coefficient\n", + " lorentz = (target / n_pos).cumsum()\n", + " gini = ((lorentz - cum_norm_weight) * weight).sum()\n", + "\n", + " # max weighted gini coefficient\n", + " gini_max = 10 * n_neg * (1 - 19 / (n_pos + 20 * n_neg))\n", + "\n", + " # normalized weighted gini coefficient\n", + " g = gini / gini_max\n", + "\n", + " return 0.5 * (g + d)\n", + "\n", + "def lgb_amex_metric(y_true, y_pred):\n", + " \"\"\"The competition metric with lightgbm's calling convention\"\"\"\n", + " return ('amex_metric_score',\n", + " amex_metric(y_true, y_pred),\n", + " True)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Feature Engineering" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "features_avg = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', \n", + " 'B_16', 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_28', 'B_29', 'B_30', \n", + " 'B_32', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', \n", + " 'D_45', 'D_46', 'D_47', 'D_48', 'D_50', 'D_51', 'D_53', 'D_54', 'D_55', 'D_58', 'D_59', 'D_60', 'D_61', \n", + " 'D_62', 'D_65', 'D_66', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_75', 'D_76', 'D_77', 'D_78', \n", + " 'D_80', 'D_82', 'D_84', 'D_86', 'D_91', 'D_92', 'D_94', 'D_96', 'D_103', 'D_104', 'D_108', 'D_112', 'D_113', \n", + " 'D_114', 'D_115', 'D_117', 'D_118', 'D_119', 'D_120', 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', \n", + " 'D_128', 'D_129', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', 'D_140', 'D_141', 'D_142', 'D_144', \n", + " 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_2', 'R_3', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_14', 'R_15', 'R_16', \n", + " 'R_17', 'R_20', 'R_21', 'R_22', 'R_24', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_9', 'S_11', 'S_12', 'S_13', \n", + " 'S_15', 'S_16', 'S_18', 'S_22', 'S_23', 'S_25', 'S_26']\n", + "features_min = ['B_2', 'B_4', 'B_5', 'B_9', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', 'B_19', 'B_20', 'B_28', 'B_29', 'B_33', 'B_36', \n", + " 'B_42', 'D_39', 'D_41', 'D_42', 'D_45', 'D_46', 'D_48', 'D_50', 'D_51', 'D_53', 'D_55', 'D_56', 'D_58', 'D_59', \n", + " 'D_60', 'D_62', 'D_70', 'D_71', 'D_74', 'D_75', 'D_78', 'D_83', 'D_102', 'D_112', 'D_113', 'D_115', 'D_118', 'D_119', \n", + " 'D_121', 'D_122', 'D_128', 'D_132', 'D_140', 'D_141', 'D_144', 'D_145', 'P_2', 'P_3', 'R_1', 'R_27', 'S_3', 'S_5', \n", + " 'S_7', 'S_9', 'S_11', 'S_12', 'S_23', 'S_25']\n", + "features_max = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', 'B_17', \n", + " 'B_18', 'B_19', 'B_21', 'B_23', 'B_24', 'B_25', 'B_29', 'B_30', 'B_33', 'B_37', 'B_38', 'B_39', 'B_40', 'B_42', 'D_39', \n", + " 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', 'D_48', 'D_49', 'D_50', 'D_52', 'D_55', 'D_56', 'D_58', 'D_59', \n", + " 'D_60', 'D_61', 'D_63', 'D_64', 'D_65', 'D_70', 'D_71', 'D_72', 'D_73', 'D_74', 'D_76', 'D_77', 'D_78', 'D_80', 'D_82', \n", + " 'D_84', 'D_91', 'D_102', 'D_105', 'D_107', 'D_110', 'D_111', 'D_112', 'D_115', 'D_116', 'D_117', 'D_118', 'D_119', \n", + " 'D_121', 'D_122', 'D_123', 'D_124', 'D_125', 'D_126', 'D_128', 'D_131', 'D_132', 'D_133', 'D_134', 'D_135', 'D_136', \n", + " 'D_138', 'D_140', 'D_141', 'D_142', 'D_144', 'D_145', 'P_2', 'P_3', 'P_4', 'R_1', 'R_3', 'R_5', 'R_6', 'R_7', 'R_8', \n", + " 'R_10', 'R_11', 'R_14', 'R_17', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_7', 'S_8', 'S_11', 'S_12', 'S_13', 'S_15', 'S_16', \n", + " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']\n", + "features_last = ['B_1', 'B_2', 'B_3', 'B_4', 'B_5', 'B_6', 'B_7', 'B_8', 'B_9', 'B_10', 'B_11', 'B_12', 'B_13', 'B_14', 'B_15', 'B_16', \n", + " 'B_17', 'B_18', 'B_19', 'B_20', 'B_21', 'B_22', 'B_23', 'B_24', 'B_25', 'B_26', 'B_28', 'B_29', 'B_30', 'B_32', 'B_33', \n", + " 'B_36', 'B_37', 'B_38', 'B_39', 'B_40', 'B_41', 'B_42', 'D_39', 'D_41', 'D_42', 'D_43', 'D_44', 'D_45', 'D_46', 'D_47', \n", + " 'D_48', 'D_49', 'D_50', 'D_51', 'D_52', 'D_53', 'D_54', 'D_55', 'D_56', 'D_58', 'D_59', 'D_60', 'D_61', 'D_62', 'D_63', \n", + " 'D_64', 'D_65', 'D_69', 'D_70', 'D_71', 'D_72', 'D_73', 'D_75', 'D_76', 'D_77', 'D_78', 'D_79', 'D_80', 'D_81', 'D_82', \n", + " 'D_83', 'D_86', 'D_91', 'D_96', 'D_105', 'D_106', 'D_112', 'D_114', 'D_119', 'D_120', 'D_121', 'D_122', 'D_124', 'D_125', \n", + " 'D_126', 'D_127', 'D_130', 'D_131', 'D_132', 'D_133', 'D_134', 'D_138', 'D_140', 'D_141', 'D_142', 'D_145', 'P_2', 'P_3', \n", + " 'P_4', 'R_1', 'R_2', 'R_3', 'R_4', 'R_5', 'R_6', 'R_7', 'R_8', 'R_9', 'R_10', 'R_11', 'R_12', 'R_13', 'R_14', 'R_15', \n", + " 'R_19', 'R_20', 'R_26', 'R_27', 'S_3', 'S_5', 'S_6', 'S_7', 'S_8', 'S_9', 'S_11', 'S_12', 'S_13', 'S_16', 'S_19', 'S_20', \n", + " 'S_22', 'S_23', 'S_24', 'S_25', 'S_26', 'S_27']" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "tags": [ + "block:feature_engineering", + "prev:load_data" + ] + }, + "outputs": [], + "source": [ + "# feature engineering gotten from https://www.kaggle.com/code/ambrosm/amex-lightgbm-quickstart\n", + "def get_features(df, \n", + " features_avg, \n", + " features_min, \n", + " features_max, \n", + " features_last\n", + " ):\n", + " '''\n", + " This function takes a dataframe with all features and returns the aggregated feature grouped by the customer id.\n", + " \n", + " df - dataframe\n", + " '''\n", + " cid = pd.Categorical(df.pop('customer_ID'), ordered=True) # get customer id\n", + " last = (cid != np.roll(cid, -1)) # mask for last statement of every customer\n", + " \n", + " df_avg = (df\n", + " .groupby(cid)\n", + " .mean()[features_avg]\n", + " .rename(columns={f: f\"{f}_avg\" for f in features_avg})\n", + " ) \n", + " \n", + " df_min = (df\n", + " .groupby(cid)\n", + " .min()[features_min]\n", + " .rename(columns={f: f\"{f}_min\" for f in features_min})\n", + " )\n", + " gc.collect()\n", + " print('Computed min')\n", + " \n", + " df_max = (df\n", + " .groupby(cid)\n", + " .max()[features_max]\n", + " .rename(columns={f: f\"{f}_max\" for f in features_max})\n", + " )\n", + " gc.collect()\n", + " print('Computed max')\n", + " \n", + " df = (df.loc[last, features_last]\n", + " .rename(columns={f: f\"{f}_last\" for f in features_last})\n", + " .set_index(np.asarray(cid[last]))\n", + " )\n", + " gc.collect()\n", + " print('Computed last')\n", + " \n", + " df_ = pd.concat([df, df_min, df_max, df_avg], axis=1, )\n", + " \n", + " del df, df_avg, df_min, df_max, cid, last\n", + " \n", + " return df_" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Computed min\n", + "Computed max\n", + "Computed last\n", + "Computed min\n", + "Computed max\n", + "Computed last\n" + ] + } + ], + "source": [ + "# apply feature engineering function\n", + "train = get_features(df_train, features_avg, features_min, features_max, features_last)\n", + "test = get_features(df_test, features_avg, features_min, features_max, features_last)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "B_1_last False\n", + "B_2_last True\n", + "B_3_last True\n", + "B_4_last False\n", + "B_5_last False\n", + " ... \n", + "S_18_avg False\n", + "S_22_avg True\n", + "S_23_avg True\n", + "S_25_avg True\n", + "S_26_avg False\n", + "Length: 469, dtype: bool" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# check null values\n", + "train.isna().any()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Modelling: StratifiedKFold\n", + "\n", + "We cross-validate with a six-fold StratifiedKFold to handle the imbalanced nature of the target.\n", + "\n", + "Lightgbm handles null values efficiently." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "tags": [ + "block:modelling", + "prev:feature_engineering" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "469 features\n", + "[20]\tvalid_0's binary_logloss: 0.267976\tvalid_0's amex_metric_score: 0.750976\n", + "Score = 0.7604229987279087\n", + "Fold 0\n", + "[20]\tvalid_0's binary_logloss: 0.267339\tvalid_0's amex_metric_score: 0.753257\n", + "Score = 0.7624180573803372\n", + "Fold 1\n", + "OOF Score: 0.76142\n" + ] + } + ], + "source": [ + "# Cross-validation\n", + "\n", + "features = [f for f in train.columns if f != 'customer_ID' and f != 'target']\n", + "\n", + "print(f\"{len(features)} features\")\n", + "\n", + "score_list = [] # lgbm score per fold\n", + "y_pred_list = [] # fold predictions list\n", + "\n", + "# init StratifiedKFold\n", + "kf = StratifiedKFold(n_splits=4)\n", + "\n", + "for fold, (idx_tr, idx_va) in enumerate(kf.split(train, target)):\n", + " \n", + " X_tr, X_va, y_tr, y_va, model = None, None, None, None, None\n", + "\n", + " X_tr = train.iloc[idx_tr][features]\n", + " X_va = train.iloc[idx_va][features]\n", + " y_tr = target[idx_tr]\n", + " y_va = target[idx_va]\n", + " \n", + " # init model\n", + " model = LGBMClassifier(n_estimators=N_EST,\n", + " learning_rate=LR, \n", + " random_state=2022)\n", + " # fit model\n", + " model.fit(X_tr, y_tr,\n", + " eval_set = [(X_va, y_va)], \n", + " eval_metric=[lgb_amex_metric],\n", + " early_stopping_rounds=30,\n", + " callbacks=[log_evaluation(20)])\n", + " \n", + " X_tr, y_tr = None, None\n", + " \n", + " # fold validation set predictions\n", + " y_va_pred = model.predict_proba(X_va, raw_score=True)\n", + " \n", + " # model score\n", + " score = amex_metric(y_va, y_va_pred)\n", + "\n", + " print(f\"Score = {score}\")\n", + " score_list.append(score)\n", + " \n", + " # test set predictions\n", + " y_pred_list.append(model.predict_proba(test[features], raw_score=True))\n", + " \n", + " print(f\"Fold {fold}\") \n", + "\n", + "# save model\n", + "joblib.dump(model, 'lgb.jl')\n", + "print(f\"OOF Score: {np.mean(score_list):.5f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# feature importance for top 30 features\n", + "fea_imp = pd.DataFrame({'imp':model.feature_importances_, 'col': features})\n", + "fea_imp = fea_imp.sort_values(['imp', 'col'], ascending=[True, False]).iloc[-30:]\n", + "_ = fea_imp.plot(kind='barh', x='col', y='imp', figsize=(20, 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Evaluation" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "tags": [ + "block:evaluation_result", + "prev:modelling" + ] + }, + "outputs": [], + "source": [ + "model = joblib.load('lgb.jl')" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "binary_logloss = model.booster_.best_score.get('valid_0').get('binary_logloss')" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "amex_metric_score = model.booster_.best_score.get('valid_0').get('amex_metric_score')" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "tags": [ + "pipeline-metrics" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.24605493989573005\n" + ] + } + ], + "source": [ + "print(binary_logloss)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "tags": [ + "pipeline-metrics" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.7625788091718922\n" + ] + } + ], + "source": [ + "print(amex_metric_score)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "## Submission" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "sub = pd.DataFrame({'customer_ID': test.index,\n", + " 'prediction': np.mean(y_pred_list, axis=0)})\n", + "sub.to_csv('submission.csv', index=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "skip" + ] + }, + "outputs": [], + "source": [ + "sub" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "kubeflow_notebook": { + "autosnapshot": true, + "experiment": { + "id": "2efb8e27-3b2e-439b-a53c-b1f9d7b94cfc", + "name": "g-research-crypto-forecasting" + }, + "experiment_name": "g-research-crypto-forecasting", + "katib_metadata": { + "algorithm": { + "algorithmName": "grid" + }, + "maxFailedTrialCount": 3, + "maxTrialCount": 12, + "objective": { + "objectiveMetricName": "", + "type": "minimize" + }, + "parallelTrialCount": 3, + "parameters": [] + }, + "katib_run": false, + "pipeline_description": "forecasting short term returns in 14 popular cryptocurrencies.", + "pipeline_name": "g-research-crypto-forecasting-pipeline", + "snapshot_volumes": true, + "steps_defaults": [ + "label:access-ml-pipeline:true", + "label:kaggle-secret:true", + "label:access-rok:true" + ], + "volume_access_mode": "rwm", + "volumes": [ + { + "annotations": [], + "mount_point": "/home/jovyan", + "name": "test-workspace-qtvmt", + "size": 32, + "size_type": "Gi", + "snapshot": false, + "type": "clone" + } + ] + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/american-express-default-kaggle-competition/requirements.txt b/american-express-default-kaggle-competition/requirements.txt index 22259d0c2..751ba674b 100644 --- a/american-express-default-kaggle-competition/requirements.txt +++ b/american-express-default-kaggle-competition/requirements.txt @@ -1,7 +1,7 @@ -kaggle -pandas -tqdm -wget -lightgbm -pyarrow -fastparquet +kaggle +pandas +tqdm +wget +lightgbm +pyarrow +fastparquet diff --git a/bluebook-for-bulldozers-kaggle-competition/Readme.md b/bluebook-for-bulldozers-kaggle-competition/Readme.md index 531a8a76c..71e58a479 100644 --- a/bluebook-for-bulldozers-kaggle-competition/Readme.md +++ b/bluebook-for-bulldozers-kaggle-competition/Readme.md @@ -1,348 +1,348 @@ -# Objective - -This example is based on the Bluebook for bulldozers competition (https://www.kaggle.com/competitions/bluebook-for-bulldozers/overview). The objective of this exercise is to predict the sale price of bulldozers sold at auctions. - -## Environment - -This pipeline was tested using Kubeflow 1.4 and kfp 1.1.2 and x86-64 and ARM based system which includes all Intel and AMD based CPU's and M1/M2 series Macbooks. - -## Step 1: Setup Kubeflow as a Service - -- If you haven’t already, sign up (https://www.arrikto.com/kubeflow-as-a-service/) -- Deploy Kubeflow - -## Step 2: Launch a Notebook Server - -- Bump memory to 2GB and vCPUs to 2 - - -## Step 3: Clone the Project Repo to Your Notebook - -- (Kubeflow as a Service) Open up a terminal in the Notebook Server and git clone the kubeflow/examples repository -``` -git clone https://github.com/kubeflow/examples -``` - -## Step 4: Setup DockerHub and Docker - -- If you haven’t already, sign up (https://hub.docker.com/) for DockerHub -- If you haven’t already, install Docker Desktop (https://www.docker.com/products/docker-desktop/) locally OR install the Docker command line utility (https://docs.docker.com/get-docker/) and enter `sudo docker login` command in your terminal and log into Docker with your your DockerHub username and password - - -## Step 5: Setup Kaggle - -- If you haven’t already done so, sign up (https://www.kaggle.com/) for Kaggle -- (On Kaggle) Generate an API token (https://www.kaggle.com/docs/api) -- (Kubeflow as a Service) Create a Kubernetes secret -``` -kubectl create secret generic kaggle-secret --from-literal=KAGGLE_USERNAME= --from-literal=KAGGLE_KEY= -``` - -## Step 6: Install Git - -- (Locally) If you don’t have it already, install Git (https://github.com/git-guides/install-git) - -## Step 7: Clone the Project Repo Locally - -- (Locally) Git clone the `kubeflow/examples` repository -``` -git clone https://github.com/kubeflow/examples -``` - -## Step 8: Create a PodDefault Resource - -- (Kubeflow as a Service) Navigate to the `bluebook-for-bulldozers-kaggle-competition directory` -- Create a resource.yaml file - -resource.yaml: -``` -apiVersion: "kubeflow.org/v1alpha1" -kind: PodDefault -metadata: - name: kaggle-access -spec: - selector: - matchLabels: - kaggle-secret: "true" - desc: "kaggle-access" - volumeMounts: - - name: secret-volume - mountPath: /secret/kaggle - volumes: - - name: secret-volume - secret: - secretName: kaggle-secret -``` - -image3 - -- Apply resource.yaml using `kubectl apply -f resource.yaml` - -## Step 9: Explore the load-data directory - -- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/load-data` directory -- Open up the `load.py` file -- Note the code in this file that will perform the actions required in the “load-data” pipeline step - -image7 - -## Step 10: Build the load Docker Image - -- (Locally) Navigate to the bluebook-for-bulldozers-kaggle-competition/pipeline-components/load-data directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` - -## Step 11: Push the load Docker Image to DockerHub - -- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/load-data` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` - -## Step 12: Explore the preprocess directory - -- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/preprocess` directory -- Open up the `preprocess.py` file -- Note the code in this file that will perform the actions required in the “preprocess” pipeline step - -image5 - -## Step 13: Build the preprocess Docker Image - -- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/preprocess` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` -## Step 14: Push the preprocess Docker Image to DockerHub - -- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/preprocess` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` - -## Step 15: Explore the train directory - -- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/train` directory -- Open up the train.py file -- Note the code in this file that will perform the actions required in the “train” pipeline step - - -![image2](https://user-images.githubusercontent.com/17012391/177051233-a32e87db-7771-4b5f-9afe-141063733262.png) - -## Step 16: Build the train Docker Image - -- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/train` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` - -## Step 17: Push the train Docker Image to DockerHub - -- (Locally) Navigate to the bluebook-for-bulldozers-kaggle-competition/pipeline-components/train directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` - -## Step 18: Explore the test directory - -- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/test` directory -- Open up the `test.py` file -- Note the code in this file that will perform the actions required in the “test” pipeline step - -image6 - -## Step 19: Build the test Docker Image - -- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/test` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` -## Step 20: Push the test Docker Image to DockerHub - -- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/test` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` - -## Step 21: Modify the blue-book-for-bulldozers-kfp.py file - -(Kubeflow as a Service) Navigate to the `bluebook-for-bulldozers-kaggle-competition` directory -Update the `bluebook-for-bulldozers-kaggle-competition-kfp.py` with accurate Docker Image inputs - -``` - return dsl.ContainerOp( - name = 'load-data', - image = '/:', - -—----- - -def PreProcess(comp1): - return dsl.ContainerOp( - name = 'preprocess', - image = '/:', - -—----- - -def Train(comp2): - return dsl.ContainerOp( - name = 'train', - image = '/:', - -—----- - -def Test(comp3): - return dsl.ContainerOp( - name = 'test', - image = '/:', - - ``` - -## Step 22: Generate a KFP Pipeline yaml File - -- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition` directory and delete the existing `blue-book-for-bulldozers-kaggle-competition-kfp.yaml` file -- (Kubeflow as a Service) Navigate to the `bluebook-for-bulldozers-kaggle-competition` directory - -Build a python virtual environment: - -Step a) Update pip -``` -python3 -m pip install --upgrade pip -``` - -Step b) Install virtualenv -``` -sudo pip3 install virtualenv -``` - -Step c) Check the installed version of venv -``` -virtualenv --version -``` - -Step d) Name your virtual enviornment as kfp -``` -virtualenv kfp -``` - -Step e) Activate your venv. -``` -source kfp/bin/activate -``` - -After this virtual environment will get activated. Now in our activated venv we need to install following packages: -``` -sudo apt-get update -sudo apt-get upgrade -sudo apt-get install -y git python3-pip - -python3 -m pip install kfp==1.1.2 -``` - -After installing packages create the yaml file - -Inside venv point your terminal to a path which contains our kfp file to build pipeline (blue-book-for-bulldozers-kaggle-competition-kfp.py) and run these commands to generate a `yaml` file for the Pipeline: - -``` -blue-book-for-bulldozers-kaggle-competition-kfp.py -``` - -Screenshot 2022-07-04 at 12 01 51 AM - -- Download the `bluebook-for-bulldozers-kaggle-competition.yaml` file that was created to your local `bluebook-for-bulldozers-kaggle-competition` directory - -## Step 23: Create an Experiment - -- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Experiments (KFP) > Create Experiment view -- Name the experiment and click Next -- Click on Experiments (KFP) to view the experiment you just created - -## Step 24: Create a Pipeline - -- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Pipelines > +Upload Pipeline view -- Name the pipeline -- Click on Upload a file -- Upload the local bluebook-for-bulldozers-kaggle-competition.py.yaml file -- Click Create - -Step 25: Create a Run - -- (Kubeflow as a Service) Click on Create Run in the view from the previous step -- Choose the experiment we created in Step 23 -- Click Start -- Click on the run name to view the runtime execution graph - -Screenshot 2022-07-04 at 12 04 43 AM - - -## Troubleshooting Tips: -While running the pipeline as mentioned above you may come across this error: -![kaggle-secret-error-01](https://user-images.githubusercontent.com/17012391/175290593-aac58d80-0d9f-47bd-bd20-46e6f5207210.PNG) - -errorlog: - -``` -kaggle.rest.ApiException: (403) -Reason: Forbidden -HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json', 'Date': 'Thu, 23 Jun 2022 11:31:18 GMT', 'Access-Control-Allow-Credentials': 'true', 'Set-Cookie': 'ka_sessionid=6817a347c75399a531148e19cad0aaeb; max-age=2626560; path=/, GCLB=CIGths3--ebbUg; path=/; HttpOnly', 'Transfer-Encoding': 'chunked', 'Vary': -HTTP response body: b'{"code":403,"message":"You must accept this competition\\u0027s rules before you\\u0027ll be able to download files."}' - -``` -This error occours for two reasons: -- Your Kaggle account is not verified with your phone number. -- Rules for this specific competitions are not accepted. - -Lets accept Rules of Bulldozers competition -![kaggle-secret-error-02](https://user-images.githubusercontent.com/17012391/175291406-7a30e06d-fc05-44c3-b33c-bccd31b381bd.PNG) - -Click on "I Understand and Accept". After this you will be prompted to verify your account using your phone number: -![kaggle-secret-error-03](https://user-images.githubusercontent.com/17012391/175291608-daad1a47-119a-4e47-b48b-4f878d65ddd7.PNG) - -Add your phone number and Kaggle will send the code to your number, enter this code and verify your account. ( Note: pipeline wont run if your Kaggle account is not verified ) - -## Success -After the kaggle account is verified pipeline run is successful we will get the following: - -Screenshot 2022-06-10 at 12 04 48 AM - - +# Objective + +This example is based on the Bluebook for bulldozers competition (https://www.kaggle.com/competitions/bluebook-for-bulldozers/overview). The objective of this exercise is to predict the sale price of bulldozers sold at auctions. + +## Environment + +This pipeline was tested using Kubeflow 1.4 and kfp 1.1.2 and x86-64 and ARM based system which includes all Intel and AMD based CPU's and M1/M2 series Macbooks. + +## Step 1: Setup Kubeflow as a Service + +- If you haven’t already, sign up (https://www.arrikto.com/kubeflow-as-a-service/) +- Deploy Kubeflow + +## Step 2: Launch a Notebook Server + +- Bump memory to 2GB and vCPUs to 2 + + +## Step 3: Clone the Project Repo to Your Notebook + +- (Kubeflow as a Service) Open up a terminal in the Notebook Server and git clone the kubeflow/examples repository +``` +git clone https://github.com/kubeflow/examples +``` + +## Step 4: Setup DockerHub and Docker + +- If you haven’t already, sign up (https://hub.docker.com/) for DockerHub +- If you haven’t already, install Docker Desktop (https://www.docker.com/products/docker-desktop/) locally OR install the Docker command line utility (https://docs.docker.com/get-docker/) and enter `sudo docker login` command in your terminal and log into Docker with your your DockerHub username and password + + +## Step 5: Setup Kaggle + +- If you haven’t already done so, sign up (https://www.kaggle.com/) for Kaggle +- (On Kaggle) Generate an API token (https://www.kaggle.com/docs/api) +- (Kubeflow as a Service) Create a Kubernetes secret +``` +kubectl create secret generic kaggle-secret --from-literal=KAGGLE_USERNAME= --from-literal=KAGGLE_KEY= +``` + +## Step 6: Install Git + +- (Locally) If you don’t have it already, install Git (https://github.com/git-guides/install-git) + +## Step 7: Clone the Project Repo Locally + +- (Locally) Git clone the `kubeflow/examples` repository +``` +git clone https://github.com/kubeflow/examples +``` + +## Step 8: Create a PodDefault Resource + +- (Kubeflow as a Service) Navigate to the `bluebook-for-bulldozers-kaggle-competition directory` +- Create a resource.yaml file + +resource.yaml: +``` +apiVersion: "kubeflow.org/v1alpha1" +kind: PodDefault +metadata: + name: kaggle-access +spec: + selector: + matchLabels: + kaggle-secret: "true" + desc: "kaggle-access" + volumeMounts: + - name: secret-volume + mountPath: /secret/kaggle + volumes: + - name: secret-volume + secret: + secretName: kaggle-secret +``` + +image3 + +- Apply resource.yaml using `kubectl apply -f resource.yaml` + +## Step 9: Explore the load-data directory + +- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/load-data` directory +- Open up the `load.py` file +- Note the code in this file that will perform the actions required in the “load-data” pipeline step + +image7 + +## Step 10: Build the load Docker Image + +- (Locally) Navigate to the bluebook-for-bulldozers-kaggle-competition/pipeline-components/load-data directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` + +## Step 11: Push the load Docker Image to DockerHub + +- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/load-data` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` + +## Step 12: Explore the preprocess directory + +- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/preprocess` directory +- Open up the `preprocess.py` file +- Note the code in this file that will perform the actions required in the “preprocess” pipeline step + +image5 + +## Step 13: Build the preprocess Docker Image + +- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/preprocess` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` +## Step 14: Push the preprocess Docker Image to DockerHub + +- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/preprocess` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` + +## Step 15: Explore the train directory + +- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/train` directory +- Open up the train.py file +- Note the code in this file that will perform the actions required in the “train” pipeline step + + +![image2](https://user-images.githubusercontent.com/17012391/177051233-a32e87db-7771-4b5f-9afe-141063733262.png) + +## Step 16: Build the train Docker Image + +- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/train` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` + +## Step 17: Push the train Docker Image to DockerHub + +- (Locally) Navigate to the bluebook-for-bulldozers-kaggle-competition/pipeline-components/train directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` + +## Step 18: Explore the test directory + +- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/test` directory +- Open up the `test.py` file +- Note the code in this file that will perform the actions required in the “test” pipeline step + +image6 + +## Step 19: Build the test Docker Image + +- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/test` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` +## Step 20: Push the test Docker Image to DockerHub + +- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition/pipeline-components/test` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` + +## Step 21: Modify the blue-book-for-bulldozers-kfp.py file + +(Kubeflow as a Service) Navigate to the `bluebook-for-bulldozers-kaggle-competition` directory +Update the `bluebook-for-bulldozers-kaggle-competition-kfp.py` with accurate Docker Image inputs + +``` + return dsl.ContainerOp( + name = 'load-data', + image = '/:', + +—----- + +def PreProcess(comp1): + return dsl.ContainerOp( + name = 'preprocess', + image = '/:', + +—----- + +def Train(comp2): + return dsl.ContainerOp( + name = 'train', + image = '/:', + +—----- + +def Test(comp3): + return dsl.ContainerOp( + name = 'test', + image = '/:', + + ``` + +## Step 22: Generate a KFP Pipeline yaml File + +- (Locally) Navigate to the `bluebook-for-bulldozers-kaggle-competition` directory and delete the existing `blue-book-for-bulldozers-kaggle-competition-kfp.yaml` file +- (Kubeflow as a Service) Navigate to the `bluebook-for-bulldozers-kaggle-competition` directory + +Build a python virtual environment: + +Step a) Update pip +``` +python3 -m pip install --upgrade pip +``` + +Step b) Install virtualenv +``` +sudo pip3 install virtualenv +``` + +Step c) Check the installed version of venv +``` +virtualenv --version +``` + +Step d) Name your virtual enviornment as kfp +``` +virtualenv kfp +``` + +Step e) Activate your venv. +``` +source kfp/bin/activate +``` + +After this virtual environment will get activated. Now in our activated venv we need to install following packages: +``` +sudo apt-get update +sudo apt-get upgrade +sudo apt-get install -y git python3-pip + +python3 -m pip install kfp==1.1.2 +``` + +After installing packages create the yaml file + +Inside venv point your terminal to a path which contains our kfp file to build pipeline (blue-book-for-bulldozers-kaggle-competition-kfp.py) and run these commands to generate a `yaml` file for the Pipeline: + +``` +blue-book-for-bulldozers-kaggle-competition-kfp.py +``` + +Screenshot 2022-07-04 at 12 01 51 AM + +- Download the `bluebook-for-bulldozers-kaggle-competition.yaml` file that was created to your local `bluebook-for-bulldozers-kaggle-competition` directory + +## Step 23: Create an Experiment + +- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Experiments (KFP) > Create Experiment view +- Name the experiment and click Next +- Click on Experiments (KFP) to view the experiment you just created + +## Step 24: Create a Pipeline + +- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Pipelines > +Upload Pipeline view +- Name the pipeline +- Click on Upload a file +- Upload the local bluebook-for-bulldozers-kaggle-competition.py.yaml file +- Click Create + +Step 25: Create a Run + +- (Kubeflow as a Service) Click on Create Run in the view from the previous step +- Choose the experiment we created in Step 23 +- Click Start +- Click on the run name to view the runtime execution graph + +Screenshot 2022-07-04 at 12 04 43 AM + + +## Troubleshooting Tips: +While running the pipeline as mentioned above you may come across this error: +![kaggle-secret-error-01](https://user-images.githubusercontent.com/17012391/175290593-aac58d80-0d9f-47bd-bd20-46e6f5207210.PNG) + +errorlog: + +``` +kaggle.rest.ApiException: (403) +Reason: Forbidden +HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json', 'Date': 'Thu, 23 Jun 2022 11:31:18 GMT', 'Access-Control-Allow-Credentials': 'true', 'Set-Cookie': 'ka_sessionid=6817a347c75399a531148e19cad0aaeb; max-age=2626560; path=/, GCLB=CIGths3--ebbUg; path=/; HttpOnly', 'Transfer-Encoding': 'chunked', 'Vary': +HTTP response body: b'{"code":403,"message":"You must accept this competition\\u0027s rules before you\\u0027ll be able to download files."}' + +``` +This error occours for two reasons: +- Your Kaggle account is not verified with your phone number. +- Rules for this specific competitions are not accepted. + +Lets accept Rules of Bulldozers competition +![kaggle-secret-error-02](https://user-images.githubusercontent.com/17012391/175291406-7a30e06d-fc05-44c3-b33c-bccd31b381bd.PNG) + +Click on "I Understand and Accept". After this you will be prompted to verify your account using your phone number: +![kaggle-secret-error-03](https://user-images.githubusercontent.com/17012391/175291608-daad1a47-119a-4e47-b48b-4f878d65ddd7.PNG) + +Add your phone number and Kaggle will send the code to your number, enter this code and verify your account. ( Note: pipeline wont run if your Kaggle account is not verified ) + +## Success +After the kaggle account is verified pipeline run is successful we will get the following: + +Screenshot 2022-06-10 at 12 04 48 AM + + diff --git a/bluebook-for-bulldozers-kaggle-competition/blue-book-for-bulldozers-kaggle-competition-kfp.py b/bluebook-for-bulldozers-kaggle-competition/blue-book-for-bulldozers-kaggle-competition-kfp.py index fc0f61523..1ed7174a1 100644 --- a/bluebook-for-bulldozers-kaggle-competition/blue-book-for-bulldozers-kaggle-competition-kfp.py +++ b/bluebook-for-bulldozers-kaggle-competition/blue-book-for-bulldozers-kaggle-competition-kfp.py @@ -1,62 +1,62 @@ -import kfp -from kfp import dsl - -def LoadData(): - vop = dsl.VolumeOp(name="pvc", - resource_name="pvc", size='1Gi', - modes=dsl.VOLUME_MODE_RWO) - - return dsl.ContainerOp( - name = 'load-data', - image = 'hubdocker76/bulldozers:v6', - command = ['python3', 'load.py'], - - pvolumes={ - '/data': vop.volume - } - ) - -def PreProcess(comp1): - return dsl.ContainerOp( - name = 'preprocess', - image = 'hubdocker76/bulldozers-preprocess:v1', - pvolumes={ - '/data': comp1.pvolumes['/data'] - }, - command = ['python3', 'preprocess.py'] - ) - -def Train(comp2): - return dsl.ContainerOp( - name = 'train', - image = 'hubdocker76/bulldozers-train:v2', - pvolumes={ - '/data': comp2.pvolumes['/data'] - }, - command = ['python3', 'train.py'] - ) - -def Test(comp3): - return dsl.ContainerOp( - name = 'test', - image = 'hubdocker76/bulldozers-test:v2', - pvolumes={ - '/data': comp3.pvolumes['/data'] - }, - command = ['python3', 'test.py'] - ) - - -@dsl.pipeline( - name = 'blue book for bulldozers', - description = 'pipeline to run blue book for bulldozers') - -def passing_parameter(): - comp1 = LoadData().add_pod_label("kaggle-secret", "true") - comp2 = PreProcess(comp1) - comp3 = Train(comp2) - comp4 = Test(comp3) - -if __name__ == '__main__': - import kfp.compiler as compiler - compiler.Compiler().compile(passing_parameter, __file__[:-3]+ '.yaml') +import kfp +from kfp import dsl + +def LoadData(): + vop = dsl.VolumeOp(name="pvc", + resource_name="pvc", size='1Gi', + modes=dsl.VOLUME_MODE_RWO) + + return dsl.ContainerOp( + name = 'load-data', + image = 'hubdocker76/bulldozers:v6', + command = ['python3', 'load.py'], + + pvolumes={ + '/data': vop.volume + } + ) + +def PreProcess(comp1): + return dsl.ContainerOp( + name = 'preprocess', + image = 'hubdocker76/bulldozers-preprocess:v1', + pvolumes={ + '/data': comp1.pvolumes['/data'] + }, + command = ['python3', 'preprocess.py'] + ) + +def Train(comp2): + return dsl.ContainerOp( + name = 'train', + image = 'hubdocker76/bulldozers-train:v2', + pvolumes={ + '/data': comp2.pvolumes['/data'] + }, + command = ['python3', 'train.py'] + ) + +def Test(comp3): + return dsl.ContainerOp( + name = 'test', + image = 'hubdocker76/bulldozers-test:v2', + pvolumes={ + '/data': comp3.pvolumes['/data'] + }, + command = ['python3', 'test.py'] + ) + + +@dsl.pipeline( + name = 'blue book for bulldozers', + description = 'pipeline to run blue book for bulldozers') + +def passing_parameter(): + comp1 = LoadData().add_pod_label("kaggle-secret", "true") + comp2 = PreProcess(comp1) + comp3 = Train(comp2) + comp4 = Test(comp3) + +if __name__ == '__main__': + import kfp.compiler as compiler + compiler.Compiler().compile(passing_parameter, __file__[:-3]+ '.yaml') diff --git a/code_search/docker/ks/launch_search_index_creator_job.sh b/code_search/docker/ks/launch_search_index_creator_job.sh old mode 100755 new mode 100644 diff --git a/code_search/docker/ks/submit_code_embeddings_job.sh b/code_search/docker/ks/submit_code_embeddings_job.sh old mode 100755 new mode 100644 diff --git a/code_search/docker/ks/update_index.sh b/code_search/docker/ks/update_index.sh old mode 100755 new mode 100644 diff --git a/code_search/docker/t2t/t2t-entrypoint.sh b/code_search/docker/t2t/t2t-entrypoint.sh old mode 100755 new mode 100644 diff --git a/code_search/docker/ui/build.sh b/code_search/docker/ui/build.sh old mode 100755 new mode 100644 diff --git a/code_search/kubeflow/environments/base.libsonnet b/code_search/kubeflow/environments/base.libsonnet deleted file mode 100644 index a129affb1..000000000 --- a/code_search/kubeflow/environments/base.libsonnet +++ /dev/null @@ -1,4 +0,0 @@ -local components = std.extVar("__ksonnet/components"); -components + { - // Insert user-specified overrides here. -} diff --git a/code_search/kubeflow/environments/cs_demo/globals.libsonnet b/code_search/kubeflow/environments/cs_demo/globals.libsonnet deleted file mode 100644 index 7055aebe1..000000000 --- a/code_search/kubeflow/environments/cs_demo/globals.libsonnet +++ /dev/null @@ -1,9 +0,0 @@ -{ - // Warning: Do not define a global "image" as that will end up overriding - // the image parameter for all components. Define more specific names - // e.g. "dataflowImage", "trainerCpuImage", "trainerGpuImage", - workingDir: "gs://code-search-demo/20181104", - dataDir: "gs://code-search-demo/20181104/data", - project: "code-search-demo", - experiment: "demo-trainer-11-07-dist-sync-gpu", -} diff --git a/code_search/kubeflow/environments/cs_demo/main.jsonnet b/code_search/kubeflow/environments/cs_demo/main.jsonnet deleted file mode 100644 index 1a44c481d..000000000 --- a/code_search/kubeflow/environments/cs_demo/main.jsonnet +++ /dev/null @@ -1,8 +0,0 @@ -local base = import "base.libsonnet"; -// uncomment if you reference ksonnet-lib -// local k = import "k.libsonnet"; - -base { - // Insert user-specified overrides here. For example if a component is named \"nginx-deployment\", you might have something like:\n") - // "nginx-deployment"+: k.deployment.mixin.metadata.labels({foo: "bar"}) -} diff --git a/code_search/kubeflow/environments/cs_demo/params.libsonnet b/code_search/kubeflow/environments/cs_demo/params.libsonnet deleted file mode 100644 index e57c4be56..000000000 --- a/code_search/kubeflow/environments/cs_demo/params.libsonnet +++ /dev/null @@ -1,22 +0,0 @@ -local params = std.extVar('__ksonnet/params'); -local globals = import 'globals.libsonnet'; -local envParams = params { - components+: { - "t2t-code-search"+: {}, - "t2t-code-search-datagen"+: { - githubTable: '', - }, - "submit-preprocess-job"+: { - githubTable: '', - }, - "search-index-server"+: { - }, - }, -}; - -{ - components: { - [x]: envParams.components[x] + globals - for x in std.objectFields(envParams.components) - }, -} \ No newline at end of file diff --git a/code_search/kubeflow/environments/pipeline/globals.libsonnet b/code_search/kubeflow/environments/pipeline/globals.libsonnet deleted file mode 100644 index 1b59385fb..000000000 --- a/code_search/kubeflow/environments/pipeline/globals.libsonnet +++ /dev/null @@ -1,7 +0,0 @@ -{ - // Warning: Do not define a global "image" as that will end up overriding - // the image parameter for all components. Define more specific names - // e.g. "dataflowImage", "trainerCpuImage", "trainerGpuImage", - experiment: "pipeline", - waitUntilFinish: "true", -} diff --git a/code_search/kubeflow/environments/pipeline/main.jsonnet b/code_search/kubeflow/environments/pipeline/main.jsonnet deleted file mode 100644 index 58695a80c..000000000 --- a/code_search/kubeflow/environments/pipeline/main.jsonnet +++ /dev/null @@ -1,8 +0,0 @@ -local base = import "base.libsonnet"; -// uncomment if you reference ksonnet-lib -// local k = import "k.libsonnet"; - -base + { - // Insert user-specified overrides here. For example if a component is named \"nginx-deployment\", you might have something like:\n") - // "nginx-deployment"+: k.deployment.mixin.metadata.labels({foo: "bar"}) -} diff --git a/code_search/kubeflow/environments/pipeline/params.libsonnet b/code_search/kubeflow/environments/pipeline/params.libsonnet deleted file mode 100644 index eb3bac704..000000000 --- a/code_search/kubeflow/environments/pipeline/params.libsonnet +++ /dev/null @@ -1,12 +0,0 @@ -local params = std.extVar("__ksonnet/params"); -local globals = import "globals.libsonnet"; -local envParams = params + { - components +: { - }, -}; - -{ - components: { - [x]: envParams.components[x] + globals, for x in std.objectFields(envParams.components) - }, -} diff --git a/code_search/src/code_search/nmslib/cli/start_test_server.sh b/code_search/src/code_search/nmslib/cli/start_test_server.sh old mode 100755 new mode 100644 diff --git a/codes/volume_parallel.py b/codes/volume_parallel.py index 988212e3d..ee9c89108 100644 --- a/codes/volume_parallel.py +++ b/codes/volume_parallel.py @@ -1,62 +1,62 @@ - -import kfp -from kfp import dsl - -def create_pv(): - return dsl.VolumeOp( - name="create_pv", - resource_name="kfp-pvc", - size="1Gi", - modes=dsl.VOLUME_MODE_RWO - ) - - -def parallel_1(vol_name: str): - cop = dsl.ContainerOp( - name='generate_data', - image='bash:5.1', - command=['sh', '-c'], - arguments=['echo 1 | tee /mnt/out1.txt'] - ) - cop.container.set_image_pull_policy('IfNotPresent') - cop.add_pvolumes({'/mnt': dsl.PipelineVolume(pvc=vol_name)}) - return cop - - -def parallel_2(vol_name: str): - cop = dsl.ContainerOp( - name='generate_data', - image='bash:5.1', - command=['sh', '-c'], - arguments=['echo 2 | tee /mnt/out2.txt'] - ) - cop.container.set_image_pull_policy('IfNotPresent') - cop.add_pvolumes({'/mnt': dsl.PipelineVolume(pvc=vol_name)}) - return cop - - -def parallel_3(vol_name: str): - cop = dsl.ContainerOp( - name='generate_data', - image='bash:5.1', - command=['sh', '-c'], - arguments=['echo 3 | tee /mnt/out3.txt'] - ) - cop.container.set_image_pull_policy('IfNotPresent') - cop.add_pvolumes({'/mnt': dsl.PipelineVolume(pvc=vol_name)}) - return cop - - -@dsl.pipeline( - name="Kubeflow volume parallel example", - description="Demonstrate the use case of volume on Kubeflow pipeline.") -def volume_parallel(): - vop = create_pv() - cop1 = parallel_1(vop.outputs["name"]).after(vop) - cop2 = parallel_2(vop.outputs["name"]).after(vop) - cop3 = parallel_3(vop.outputs["name"]).after(vop) - - -if __name__ == "__main__": - import kfp.compiler as compiler + +import kfp +from kfp import dsl + +def create_pv(): + return dsl.VolumeOp( + name="create_pv", + resource_name="kfp-pvc", + size="1Gi", + modes=dsl.VOLUME_MODE_RWO + ) + + +def parallel_1(vol_name: str): + cop = dsl.ContainerOp( + name='generate_data', + image='bash:5.1', + command=['sh', '-c'], + arguments=['echo 1 | tee /mnt/out1.txt'] + ) + cop.container.set_image_pull_policy('IfNotPresent') + cop.add_pvolumes({'/mnt': dsl.PipelineVolume(pvc=vol_name)}) + return cop + + +def parallel_2(vol_name: str): + cop = dsl.ContainerOp( + name='generate_data', + image='bash:5.1', + command=['sh', '-c'], + arguments=['echo 2 | tee /mnt/out2.txt'] + ) + cop.container.set_image_pull_policy('IfNotPresent') + cop.add_pvolumes({'/mnt': dsl.PipelineVolume(pvc=vol_name)}) + return cop + + +def parallel_3(vol_name: str): + cop = dsl.ContainerOp( + name='generate_data', + image='bash:5.1', + command=['sh', '-c'], + arguments=['echo 3 | tee /mnt/out3.txt'] + ) + cop.container.set_image_pull_policy('IfNotPresent') + cop.add_pvolumes({'/mnt': dsl.PipelineVolume(pvc=vol_name)}) + return cop + + +@dsl.pipeline( + name="Kubeflow volume parallel example", + description="Demonstrate the use case of volume on Kubeflow pipeline.") +def volume_parallel(): + vop = create_pv() + cop1 = parallel_1(vop.outputs["name"]).after(vop) + cop2 = parallel_2(vop.outputs["name"]).after(vop) + cop3 = parallel_3(vop.outputs["name"]).after(vop) + + +if __name__ == "__main__": + import kfp.compiler as compiler compiler.Compiler().compile(volume_parallel, __file__ + ".yaml") \ No newline at end of file diff --git a/demos/simple_pipeline/gpu-example-pipeline.py b/demos/simple_pipeline/gpu-example-pipeline.py old mode 100755 new mode 100644 diff --git a/demos/yelp_demo/demo_setup/create_context.sh b/demos/yelp_demo/demo_setup/create_context.sh old mode 100755 new mode 100644 diff --git a/demos/yelp_demo/pipelines/gpu-example-pipeline.py b/demos/yelp_demo/pipelines/gpu-example-pipeline.py old mode 100755 new mode 100644 diff --git a/demos/yelp_demo/yelp/yelp_sentiment/worker_launcher.sh b/demos/yelp_demo/yelp/yelp_sentiment/worker_launcher.sh old mode 100755 new mode 100644 diff --git a/digit-recognition-kaggle-competition/data/sample_submission.csv b/digit-recognition-kaggle-competition/data/sample_submission.csv index f5becf714..7ea007bbf 100644 --- a/digit-recognition-kaggle-competition/data/sample_submission.csv +++ b/digit-recognition-kaggle-competition/data/sample_submission.csv @@ -1,28001 +1,28001 @@ -ImageId,Label -1,0 -2,0 -3,0 -4,0 -5,0 -6,0 -7,0 -8,0 -9,0 -10,0 -11,0 -12,0 -13,0 -14,0 -15,0 -16,0 -17,0 -18,0 -19,0 -20,0 -21,0 -22,0 -23,0 -24,0 -25,0 -26,0 -27,0 -28,0 -29,0 -30,0 -31,0 -32,0 -33,0 -34,0 -35,0 -36,0 -37,0 -38,0 -39,0 -40,0 -41,0 -42,0 -43,0 -44,0 -45,0 -46,0 -47,0 -48,0 -49,0 -50,0 -51,0 -52,0 -53,0 -54,0 -55,0 -56,0 -57,0 -58,0 -59,0 -60,0 -61,0 -62,0 -63,0 -64,0 -65,0 -66,0 -67,0 -68,0 -69,0 -70,0 -71,0 -72,0 -73,0 -74,0 -75,0 -76,0 -77,0 -78,0 -79,0 -80,0 -81,0 -82,0 -83,0 -84,0 -85,0 -86,0 -87,0 -88,0 -89,0 -90,0 -91,0 -92,0 -93,0 -94,0 -95,0 -96,0 -97,0 -98,0 -99,0 -100,0 -101,0 -102,0 -103,0 -104,0 -105,0 -106,0 -107,0 -108,0 -109,0 -110,0 -111,0 -112,0 -113,0 -114,0 -115,0 -116,0 -117,0 -118,0 -119,0 -120,0 -121,0 -122,0 -123,0 -124,0 -125,0 -126,0 -127,0 -128,0 -129,0 -130,0 -131,0 -132,0 -133,0 -134,0 -135,0 -136,0 -137,0 -138,0 -139,0 -140,0 -141,0 -142,0 -143,0 -144,0 -145,0 -146,0 -147,0 -148,0 -149,0 -150,0 -151,0 -152,0 -153,0 -154,0 -155,0 -156,0 -157,0 -158,0 -159,0 -160,0 -161,0 -162,0 -163,0 -164,0 -165,0 -166,0 -167,0 -168,0 -169,0 -170,0 -171,0 -172,0 -173,0 -174,0 -175,0 -176,0 -177,0 -178,0 -179,0 -180,0 -181,0 -182,0 -183,0 -184,0 -185,0 -186,0 -187,0 -188,0 -189,0 -190,0 -191,0 -192,0 -193,0 -194,0 -195,0 -196,0 -197,0 -198,0 -199,0 -200,0 -201,0 -202,0 -203,0 -204,0 -205,0 -206,0 -207,0 -208,0 -209,0 -210,0 -211,0 -212,0 -213,0 -214,0 -215,0 -216,0 -217,0 -218,0 -219,0 -220,0 -221,0 -222,0 -223,0 -224,0 -225,0 -226,0 -227,0 -228,0 -229,0 -230,0 -231,0 -232,0 -233,0 -234,0 -235,0 -236,0 -237,0 -238,0 -239,0 -240,0 -241,0 -242,0 -243,0 -244,0 -245,0 -246,0 -247,0 -248,0 -249,0 -250,0 -251,0 -252,0 -253,0 -254,0 -255,0 -256,0 -257,0 -258,0 -259,0 -260,0 -261,0 -262,0 -263,0 -264,0 -265,0 -266,0 -267,0 -268,0 -269,0 -270,0 -271,0 -272,0 -273,0 -274,0 -275,0 -276,0 -277,0 -278,0 -279,0 -280,0 -281,0 -282,0 -283,0 -284,0 -285,0 -286,0 -287,0 -288,0 -289,0 -290,0 -291,0 -292,0 -293,0 -294,0 -295,0 -296,0 -297,0 -298,0 -299,0 -300,0 -301,0 -302,0 -303,0 -304,0 -305,0 -306,0 -307,0 -308,0 -309,0 -310,0 -311,0 -312,0 -313,0 -314,0 -315,0 -316,0 -317,0 -318,0 -319,0 -320,0 -321,0 -322,0 -323,0 -324,0 -325,0 -326,0 -327,0 -328,0 -329,0 -330,0 -331,0 -332,0 -333,0 -334,0 -335,0 -336,0 -337,0 -338,0 -339,0 -340,0 -341,0 -342,0 -343,0 -344,0 -345,0 -346,0 -347,0 -348,0 -349,0 -350,0 -351,0 -352,0 -353,0 -354,0 -355,0 -356,0 -357,0 -358,0 -359,0 -360,0 -361,0 -362,0 -363,0 -364,0 -365,0 -366,0 -367,0 -368,0 -369,0 -370,0 -371,0 -372,0 -373,0 -374,0 -375,0 -376,0 -377,0 -378,0 -379,0 -380,0 -381,0 -382,0 -383,0 -384,0 -385,0 -386,0 -387,0 -388,0 -389,0 -390,0 -391,0 -392,0 -393,0 -394,0 -395,0 -396,0 -397,0 -398,0 -399,0 -400,0 -401,0 -402,0 -403,0 -404,0 -405,0 -406,0 -407,0 -408,0 -409,0 -410,0 -411,0 -412,0 -413,0 -414,0 -415,0 -416,0 -417,0 -418,0 -419,0 -420,0 -421,0 -422,0 -423,0 -424,0 -425,0 -426,0 -427,0 -428,0 -429,0 -430,0 -431,0 -432,0 -433,0 -434,0 -435,0 -436,0 -437,0 -438,0 -439,0 -440,0 -441,0 -442,0 -443,0 -444,0 -445,0 -446,0 -447,0 -448,0 -449,0 -450,0 -451,0 -452,0 -453,0 -454,0 -455,0 -456,0 -457,0 -458,0 -459,0 -460,0 -461,0 -462,0 -463,0 -464,0 -465,0 -466,0 -467,0 -468,0 -469,0 -470,0 -471,0 -472,0 -473,0 -474,0 -475,0 -476,0 -477,0 -478,0 -479,0 -480,0 -481,0 -482,0 -483,0 -484,0 -485,0 -486,0 -487,0 -488,0 -489,0 -490,0 -491,0 -492,0 -493,0 -494,0 -495,0 -496,0 -497,0 -498,0 -499,0 -500,0 -501,0 -502,0 -503,0 -504,0 -505,0 -506,0 -507,0 -508,0 -509,0 -510,0 -511,0 -512,0 -513,0 -514,0 -515,0 -516,0 -517,0 -518,0 -519,0 -520,0 -521,0 -522,0 -523,0 -524,0 -525,0 -526,0 -527,0 -528,0 -529,0 -530,0 -531,0 -532,0 -533,0 -534,0 -535,0 -536,0 -537,0 -538,0 -539,0 -540,0 -541,0 -542,0 -543,0 -544,0 -545,0 -546,0 -547,0 -548,0 -549,0 -550,0 -551,0 -552,0 -553,0 -554,0 -555,0 -556,0 -557,0 -558,0 -559,0 -560,0 -561,0 -562,0 -563,0 -564,0 -565,0 -566,0 -567,0 -568,0 -569,0 -570,0 -571,0 -572,0 -573,0 -574,0 -575,0 -576,0 -577,0 -578,0 -579,0 -580,0 -581,0 -582,0 -583,0 -584,0 -585,0 -586,0 -587,0 -588,0 -589,0 -590,0 -591,0 -592,0 -593,0 -594,0 -595,0 -596,0 -597,0 -598,0 -599,0 -600,0 -601,0 -602,0 -603,0 -604,0 -605,0 -606,0 -607,0 -608,0 -609,0 -610,0 -611,0 -612,0 -613,0 -614,0 -615,0 -616,0 -617,0 -618,0 -619,0 -620,0 -621,0 -622,0 -623,0 -624,0 -625,0 -626,0 -627,0 -628,0 -629,0 -630,0 -631,0 -632,0 -633,0 -634,0 -635,0 -636,0 -637,0 -638,0 -639,0 -640,0 -641,0 -642,0 -643,0 -644,0 -645,0 -646,0 -647,0 -648,0 -649,0 -650,0 -651,0 -652,0 -653,0 -654,0 -655,0 -656,0 -657,0 -658,0 -659,0 -660,0 -661,0 -662,0 -663,0 -664,0 -665,0 -666,0 -667,0 -668,0 -669,0 -670,0 -671,0 -672,0 -673,0 -674,0 -675,0 -676,0 -677,0 -678,0 -679,0 -680,0 -681,0 -682,0 -683,0 -684,0 -685,0 -686,0 -687,0 -688,0 -689,0 -690,0 -691,0 -692,0 -693,0 -694,0 -695,0 -696,0 -697,0 -698,0 -699,0 -700,0 -701,0 -702,0 -703,0 -704,0 -705,0 -706,0 -707,0 -708,0 -709,0 -710,0 -711,0 -712,0 -713,0 -714,0 -715,0 -716,0 -717,0 -718,0 -719,0 -720,0 -721,0 -722,0 -723,0 -724,0 -725,0 -726,0 -727,0 -728,0 -729,0 -730,0 -731,0 -732,0 -733,0 -734,0 -735,0 -736,0 -737,0 -738,0 -739,0 -740,0 -741,0 -742,0 -743,0 -744,0 -745,0 -746,0 -747,0 -748,0 -749,0 -750,0 -751,0 -752,0 -753,0 -754,0 -755,0 -756,0 -757,0 -758,0 -759,0 -760,0 -761,0 -762,0 -763,0 -764,0 -765,0 -766,0 -767,0 -768,0 -769,0 -770,0 -771,0 -772,0 -773,0 -774,0 -775,0 -776,0 -777,0 -778,0 -779,0 -780,0 -781,0 -782,0 -783,0 -784,0 -785,0 -786,0 -787,0 -788,0 -789,0 -790,0 -791,0 -792,0 -793,0 -794,0 -795,0 -796,0 -797,0 -798,0 -799,0 -800,0 -801,0 -802,0 -803,0 -804,0 -805,0 -806,0 -807,0 -808,0 -809,0 -810,0 -811,0 -812,0 -813,0 -814,0 -815,0 -816,0 -817,0 -818,0 -819,0 -820,0 -821,0 -822,0 -823,0 -824,0 -825,0 -826,0 -827,0 -828,0 -829,0 -830,0 -831,0 -832,0 -833,0 -834,0 -835,0 -836,0 -837,0 -838,0 -839,0 -840,0 -841,0 -842,0 -843,0 -844,0 -845,0 -846,0 -847,0 -848,0 -849,0 -850,0 -851,0 -852,0 -853,0 -854,0 -855,0 -856,0 -857,0 -858,0 -859,0 -860,0 -861,0 -862,0 -863,0 -864,0 -865,0 -866,0 -867,0 -868,0 -869,0 -870,0 -871,0 -872,0 -873,0 -874,0 -875,0 -876,0 -877,0 -878,0 -879,0 -880,0 -881,0 -882,0 -883,0 -884,0 -885,0 -886,0 -887,0 -888,0 -889,0 -890,0 -891,0 -892,0 -893,0 -894,0 -895,0 -896,0 -897,0 -898,0 -899,0 -900,0 -901,0 -902,0 -903,0 -904,0 -905,0 -906,0 -907,0 -908,0 -909,0 -910,0 -911,0 -912,0 -913,0 -914,0 -915,0 -916,0 -917,0 -918,0 -919,0 -920,0 -921,0 -922,0 -923,0 -924,0 -925,0 -926,0 -927,0 -928,0 -929,0 -930,0 -931,0 -932,0 -933,0 -934,0 -935,0 -936,0 -937,0 -938,0 -939,0 -940,0 -941,0 -942,0 -943,0 -944,0 -945,0 -946,0 -947,0 -948,0 -949,0 -950,0 -951,0 -952,0 -953,0 -954,0 -955,0 -956,0 -957,0 -958,0 -959,0 -960,0 -961,0 -962,0 -963,0 -964,0 -965,0 -966,0 -967,0 -968,0 -969,0 -970,0 -971,0 -972,0 -973,0 -974,0 -975,0 -976,0 -977,0 -978,0 -979,0 -980,0 -981,0 -982,0 -983,0 -984,0 -985,0 -986,0 -987,0 -988,0 -989,0 -990,0 -991,0 -992,0 -993,0 -994,0 -995,0 -996,0 -997,0 -998,0 -999,0 -1000,0 -1001,0 -1002,0 -1003,0 -1004,0 -1005,0 -1006,0 -1007,0 -1008,0 -1009,0 -1010,0 -1011,0 -1012,0 -1013,0 -1014,0 -1015,0 -1016,0 -1017,0 -1018,0 -1019,0 -1020,0 -1021,0 -1022,0 -1023,0 -1024,0 -1025,0 -1026,0 -1027,0 -1028,0 -1029,0 -1030,0 -1031,0 -1032,0 -1033,0 -1034,0 -1035,0 -1036,0 -1037,0 -1038,0 -1039,0 -1040,0 -1041,0 -1042,0 -1043,0 -1044,0 -1045,0 -1046,0 -1047,0 -1048,0 -1049,0 -1050,0 -1051,0 -1052,0 -1053,0 -1054,0 -1055,0 -1056,0 -1057,0 -1058,0 -1059,0 -1060,0 -1061,0 -1062,0 -1063,0 -1064,0 -1065,0 -1066,0 -1067,0 -1068,0 -1069,0 -1070,0 -1071,0 -1072,0 -1073,0 -1074,0 -1075,0 -1076,0 -1077,0 -1078,0 -1079,0 -1080,0 -1081,0 -1082,0 -1083,0 -1084,0 -1085,0 -1086,0 -1087,0 -1088,0 -1089,0 -1090,0 -1091,0 -1092,0 -1093,0 -1094,0 -1095,0 -1096,0 -1097,0 -1098,0 -1099,0 -1100,0 -1101,0 -1102,0 -1103,0 -1104,0 -1105,0 -1106,0 -1107,0 -1108,0 -1109,0 -1110,0 -1111,0 -1112,0 -1113,0 -1114,0 -1115,0 -1116,0 -1117,0 -1118,0 -1119,0 -1120,0 -1121,0 -1122,0 -1123,0 -1124,0 -1125,0 -1126,0 -1127,0 -1128,0 -1129,0 -1130,0 -1131,0 -1132,0 -1133,0 -1134,0 -1135,0 -1136,0 -1137,0 -1138,0 -1139,0 -1140,0 -1141,0 -1142,0 -1143,0 -1144,0 -1145,0 -1146,0 -1147,0 -1148,0 -1149,0 -1150,0 -1151,0 -1152,0 -1153,0 -1154,0 -1155,0 -1156,0 -1157,0 -1158,0 -1159,0 -1160,0 -1161,0 -1162,0 -1163,0 -1164,0 -1165,0 -1166,0 -1167,0 -1168,0 -1169,0 -1170,0 -1171,0 -1172,0 -1173,0 -1174,0 -1175,0 -1176,0 -1177,0 -1178,0 -1179,0 -1180,0 -1181,0 -1182,0 -1183,0 -1184,0 -1185,0 -1186,0 -1187,0 -1188,0 -1189,0 -1190,0 -1191,0 -1192,0 -1193,0 -1194,0 -1195,0 -1196,0 -1197,0 -1198,0 -1199,0 -1200,0 -1201,0 -1202,0 -1203,0 -1204,0 -1205,0 -1206,0 -1207,0 -1208,0 -1209,0 -1210,0 -1211,0 -1212,0 -1213,0 -1214,0 -1215,0 -1216,0 -1217,0 -1218,0 -1219,0 -1220,0 -1221,0 -1222,0 -1223,0 -1224,0 -1225,0 -1226,0 -1227,0 -1228,0 -1229,0 -1230,0 -1231,0 -1232,0 -1233,0 -1234,0 -1235,0 -1236,0 -1237,0 -1238,0 -1239,0 -1240,0 -1241,0 -1242,0 -1243,0 -1244,0 -1245,0 -1246,0 -1247,0 -1248,0 -1249,0 -1250,0 -1251,0 -1252,0 -1253,0 -1254,0 -1255,0 -1256,0 -1257,0 -1258,0 -1259,0 -1260,0 -1261,0 -1262,0 -1263,0 -1264,0 -1265,0 -1266,0 -1267,0 -1268,0 -1269,0 -1270,0 -1271,0 -1272,0 -1273,0 -1274,0 -1275,0 -1276,0 -1277,0 -1278,0 -1279,0 -1280,0 -1281,0 -1282,0 -1283,0 -1284,0 -1285,0 -1286,0 -1287,0 -1288,0 -1289,0 -1290,0 -1291,0 -1292,0 -1293,0 -1294,0 -1295,0 -1296,0 -1297,0 -1298,0 -1299,0 -1300,0 -1301,0 -1302,0 -1303,0 -1304,0 -1305,0 -1306,0 -1307,0 -1308,0 -1309,0 -1310,0 -1311,0 -1312,0 -1313,0 -1314,0 -1315,0 -1316,0 -1317,0 -1318,0 -1319,0 -1320,0 -1321,0 -1322,0 -1323,0 -1324,0 -1325,0 -1326,0 -1327,0 -1328,0 -1329,0 -1330,0 -1331,0 -1332,0 -1333,0 -1334,0 -1335,0 -1336,0 -1337,0 -1338,0 -1339,0 -1340,0 -1341,0 -1342,0 -1343,0 -1344,0 -1345,0 -1346,0 -1347,0 -1348,0 -1349,0 -1350,0 -1351,0 -1352,0 -1353,0 -1354,0 -1355,0 -1356,0 -1357,0 -1358,0 -1359,0 -1360,0 -1361,0 -1362,0 -1363,0 -1364,0 -1365,0 -1366,0 -1367,0 -1368,0 -1369,0 -1370,0 -1371,0 -1372,0 -1373,0 -1374,0 -1375,0 -1376,0 -1377,0 -1378,0 -1379,0 -1380,0 -1381,0 -1382,0 -1383,0 -1384,0 -1385,0 -1386,0 -1387,0 -1388,0 -1389,0 -1390,0 -1391,0 -1392,0 -1393,0 -1394,0 -1395,0 -1396,0 -1397,0 -1398,0 -1399,0 -1400,0 -1401,0 -1402,0 -1403,0 -1404,0 -1405,0 -1406,0 -1407,0 -1408,0 -1409,0 -1410,0 -1411,0 -1412,0 -1413,0 -1414,0 -1415,0 -1416,0 -1417,0 -1418,0 -1419,0 -1420,0 -1421,0 -1422,0 -1423,0 -1424,0 -1425,0 -1426,0 -1427,0 -1428,0 -1429,0 -1430,0 -1431,0 -1432,0 -1433,0 -1434,0 -1435,0 -1436,0 -1437,0 -1438,0 -1439,0 -1440,0 -1441,0 -1442,0 -1443,0 -1444,0 -1445,0 -1446,0 -1447,0 -1448,0 -1449,0 -1450,0 -1451,0 -1452,0 -1453,0 -1454,0 -1455,0 -1456,0 -1457,0 -1458,0 -1459,0 -1460,0 -1461,0 -1462,0 -1463,0 -1464,0 -1465,0 -1466,0 -1467,0 -1468,0 -1469,0 -1470,0 -1471,0 -1472,0 -1473,0 -1474,0 -1475,0 -1476,0 -1477,0 -1478,0 -1479,0 -1480,0 -1481,0 -1482,0 -1483,0 -1484,0 -1485,0 -1486,0 -1487,0 -1488,0 -1489,0 -1490,0 -1491,0 -1492,0 -1493,0 -1494,0 -1495,0 -1496,0 -1497,0 -1498,0 -1499,0 -1500,0 -1501,0 -1502,0 -1503,0 -1504,0 -1505,0 -1506,0 -1507,0 -1508,0 -1509,0 -1510,0 -1511,0 -1512,0 -1513,0 -1514,0 -1515,0 -1516,0 -1517,0 -1518,0 -1519,0 -1520,0 -1521,0 -1522,0 -1523,0 -1524,0 -1525,0 -1526,0 -1527,0 -1528,0 -1529,0 -1530,0 -1531,0 -1532,0 -1533,0 -1534,0 -1535,0 -1536,0 -1537,0 -1538,0 -1539,0 -1540,0 -1541,0 -1542,0 -1543,0 -1544,0 -1545,0 -1546,0 -1547,0 -1548,0 -1549,0 -1550,0 -1551,0 -1552,0 -1553,0 -1554,0 -1555,0 -1556,0 -1557,0 -1558,0 -1559,0 -1560,0 -1561,0 -1562,0 -1563,0 -1564,0 -1565,0 -1566,0 -1567,0 -1568,0 -1569,0 -1570,0 -1571,0 -1572,0 -1573,0 -1574,0 -1575,0 -1576,0 -1577,0 -1578,0 -1579,0 -1580,0 -1581,0 -1582,0 -1583,0 -1584,0 -1585,0 -1586,0 -1587,0 -1588,0 -1589,0 -1590,0 -1591,0 -1592,0 -1593,0 -1594,0 -1595,0 -1596,0 -1597,0 -1598,0 -1599,0 -1600,0 -1601,0 -1602,0 -1603,0 -1604,0 -1605,0 -1606,0 -1607,0 -1608,0 -1609,0 -1610,0 -1611,0 -1612,0 -1613,0 -1614,0 -1615,0 -1616,0 -1617,0 -1618,0 -1619,0 -1620,0 -1621,0 -1622,0 -1623,0 -1624,0 -1625,0 -1626,0 -1627,0 -1628,0 -1629,0 -1630,0 -1631,0 -1632,0 -1633,0 -1634,0 -1635,0 -1636,0 -1637,0 -1638,0 -1639,0 -1640,0 -1641,0 -1642,0 -1643,0 -1644,0 -1645,0 -1646,0 -1647,0 -1648,0 -1649,0 -1650,0 -1651,0 -1652,0 -1653,0 -1654,0 -1655,0 -1656,0 -1657,0 -1658,0 -1659,0 -1660,0 -1661,0 -1662,0 -1663,0 -1664,0 -1665,0 -1666,0 -1667,0 -1668,0 -1669,0 -1670,0 -1671,0 -1672,0 -1673,0 -1674,0 -1675,0 -1676,0 -1677,0 -1678,0 -1679,0 -1680,0 -1681,0 -1682,0 -1683,0 -1684,0 -1685,0 -1686,0 -1687,0 -1688,0 -1689,0 -1690,0 -1691,0 -1692,0 -1693,0 -1694,0 -1695,0 -1696,0 -1697,0 -1698,0 -1699,0 -1700,0 -1701,0 -1702,0 -1703,0 -1704,0 -1705,0 -1706,0 -1707,0 -1708,0 -1709,0 -1710,0 -1711,0 -1712,0 -1713,0 -1714,0 -1715,0 -1716,0 -1717,0 -1718,0 -1719,0 -1720,0 -1721,0 -1722,0 -1723,0 -1724,0 -1725,0 -1726,0 -1727,0 -1728,0 -1729,0 -1730,0 -1731,0 -1732,0 -1733,0 -1734,0 -1735,0 -1736,0 -1737,0 -1738,0 -1739,0 -1740,0 -1741,0 -1742,0 -1743,0 -1744,0 -1745,0 -1746,0 -1747,0 -1748,0 -1749,0 -1750,0 -1751,0 -1752,0 -1753,0 -1754,0 -1755,0 -1756,0 -1757,0 -1758,0 -1759,0 -1760,0 -1761,0 -1762,0 -1763,0 -1764,0 -1765,0 -1766,0 -1767,0 -1768,0 -1769,0 -1770,0 -1771,0 -1772,0 -1773,0 -1774,0 -1775,0 -1776,0 -1777,0 -1778,0 -1779,0 -1780,0 -1781,0 -1782,0 -1783,0 -1784,0 -1785,0 -1786,0 -1787,0 -1788,0 -1789,0 -1790,0 -1791,0 -1792,0 -1793,0 -1794,0 -1795,0 -1796,0 -1797,0 -1798,0 -1799,0 -1800,0 -1801,0 -1802,0 -1803,0 -1804,0 -1805,0 -1806,0 -1807,0 -1808,0 -1809,0 -1810,0 -1811,0 -1812,0 -1813,0 -1814,0 -1815,0 -1816,0 -1817,0 -1818,0 -1819,0 -1820,0 -1821,0 -1822,0 -1823,0 -1824,0 -1825,0 -1826,0 -1827,0 -1828,0 -1829,0 -1830,0 -1831,0 -1832,0 -1833,0 -1834,0 -1835,0 -1836,0 -1837,0 -1838,0 -1839,0 -1840,0 -1841,0 -1842,0 -1843,0 -1844,0 -1845,0 -1846,0 -1847,0 -1848,0 -1849,0 -1850,0 -1851,0 -1852,0 -1853,0 -1854,0 -1855,0 -1856,0 -1857,0 -1858,0 -1859,0 -1860,0 -1861,0 -1862,0 -1863,0 -1864,0 -1865,0 -1866,0 -1867,0 -1868,0 -1869,0 -1870,0 -1871,0 -1872,0 -1873,0 -1874,0 -1875,0 -1876,0 -1877,0 -1878,0 -1879,0 -1880,0 -1881,0 -1882,0 -1883,0 -1884,0 -1885,0 -1886,0 -1887,0 -1888,0 -1889,0 -1890,0 -1891,0 -1892,0 -1893,0 -1894,0 -1895,0 -1896,0 -1897,0 -1898,0 -1899,0 -1900,0 -1901,0 -1902,0 -1903,0 -1904,0 -1905,0 -1906,0 -1907,0 -1908,0 -1909,0 -1910,0 -1911,0 -1912,0 -1913,0 -1914,0 -1915,0 -1916,0 -1917,0 -1918,0 -1919,0 -1920,0 -1921,0 -1922,0 -1923,0 -1924,0 -1925,0 -1926,0 -1927,0 -1928,0 -1929,0 -1930,0 -1931,0 -1932,0 -1933,0 -1934,0 -1935,0 -1936,0 -1937,0 -1938,0 -1939,0 -1940,0 -1941,0 -1942,0 -1943,0 -1944,0 -1945,0 -1946,0 -1947,0 -1948,0 -1949,0 -1950,0 -1951,0 -1952,0 -1953,0 -1954,0 -1955,0 -1956,0 -1957,0 -1958,0 -1959,0 -1960,0 -1961,0 -1962,0 -1963,0 -1964,0 -1965,0 -1966,0 -1967,0 -1968,0 -1969,0 -1970,0 -1971,0 -1972,0 -1973,0 -1974,0 -1975,0 -1976,0 -1977,0 -1978,0 -1979,0 -1980,0 -1981,0 -1982,0 -1983,0 -1984,0 -1985,0 -1986,0 -1987,0 -1988,0 -1989,0 -1990,0 -1991,0 -1992,0 -1993,0 -1994,0 -1995,0 -1996,0 -1997,0 -1998,0 -1999,0 -2000,0 -2001,0 -2002,0 -2003,0 -2004,0 -2005,0 -2006,0 -2007,0 -2008,0 -2009,0 -2010,0 -2011,0 -2012,0 -2013,0 -2014,0 -2015,0 -2016,0 -2017,0 -2018,0 -2019,0 -2020,0 -2021,0 -2022,0 -2023,0 -2024,0 -2025,0 -2026,0 -2027,0 -2028,0 -2029,0 -2030,0 -2031,0 -2032,0 -2033,0 -2034,0 -2035,0 -2036,0 -2037,0 -2038,0 -2039,0 -2040,0 -2041,0 -2042,0 -2043,0 -2044,0 -2045,0 -2046,0 -2047,0 -2048,0 -2049,0 -2050,0 -2051,0 -2052,0 -2053,0 -2054,0 -2055,0 -2056,0 -2057,0 -2058,0 -2059,0 -2060,0 -2061,0 -2062,0 -2063,0 -2064,0 -2065,0 -2066,0 -2067,0 -2068,0 -2069,0 -2070,0 -2071,0 -2072,0 -2073,0 -2074,0 -2075,0 -2076,0 -2077,0 -2078,0 -2079,0 -2080,0 -2081,0 -2082,0 -2083,0 -2084,0 -2085,0 -2086,0 -2087,0 -2088,0 -2089,0 -2090,0 -2091,0 -2092,0 -2093,0 -2094,0 -2095,0 -2096,0 -2097,0 -2098,0 -2099,0 -2100,0 -2101,0 -2102,0 -2103,0 -2104,0 -2105,0 -2106,0 -2107,0 -2108,0 -2109,0 -2110,0 -2111,0 -2112,0 -2113,0 -2114,0 -2115,0 -2116,0 -2117,0 -2118,0 -2119,0 -2120,0 -2121,0 -2122,0 -2123,0 -2124,0 -2125,0 -2126,0 -2127,0 -2128,0 -2129,0 -2130,0 -2131,0 -2132,0 -2133,0 -2134,0 -2135,0 -2136,0 -2137,0 -2138,0 -2139,0 -2140,0 -2141,0 -2142,0 -2143,0 -2144,0 -2145,0 -2146,0 -2147,0 -2148,0 -2149,0 -2150,0 -2151,0 -2152,0 -2153,0 -2154,0 -2155,0 -2156,0 -2157,0 -2158,0 -2159,0 -2160,0 -2161,0 -2162,0 -2163,0 -2164,0 -2165,0 -2166,0 -2167,0 -2168,0 -2169,0 -2170,0 -2171,0 -2172,0 -2173,0 -2174,0 -2175,0 -2176,0 -2177,0 -2178,0 -2179,0 -2180,0 -2181,0 -2182,0 -2183,0 -2184,0 -2185,0 -2186,0 -2187,0 -2188,0 -2189,0 -2190,0 -2191,0 -2192,0 -2193,0 -2194,0 -2195,0 -2196,0 -2197,0 -2198,0 -2199,0 -2200,0 -2201,0 -2202,0 -2203,0 -2204,0 -2205,0 -2206,0 -2207,0 -2208,0 -2209,0 -2210,0 -2211,0 -2212,0 -2213,0 -2214,0 -2215,0 -2216,0 -2217,0 -2218,0 -2219,0 -2220,0 -2221,0 -2222,0 -2223,0 -2224,0 -2225,0 -2226,0 -2227,0 -2228,0 -2229,0 -2230,0 -2231,0 -2232,0 -2233,0 -2234,0 -2235,0 -2236,0 -2237,0 -2238,0 -2239,0 -2240,0 -2241,0 -2242,0 -2243,0 -2244,0 -2245,0 -2246,0 -2247,0 -2248,0 -2249,0 -2250,0 -2251,0 -2252,0 -2253,0 -2254,0 -2255,0 -2256,0 -2257,0 -2258,0 -2259,0 -2260,0 -2261,0 -2262,0 -2263,0 -2264,0 -2265,0 -2266,0 -2267,0 -2268,0 -2269,0 -2270,0 -2271,0 -2272,0 -2273,0 -2274,0 -2275,0 -2276,0 -2277,0 -2278,0 -2279,0 -2280,0 -2281,0 -2282,0 -2283,0 -2284,0 -2285,0 -2286,0 -2287,0 -2288,0 -2289,0 -2290,0 -2291,0 -2292,0 -2293,0 -2294,0 -2295,0 -2296,0 -2297,0 -2298,0 -2299,0 -2300,0 -2301,0 -2302,0 -2303,0 -2304,0 -2305,0 -2306,0 -2307,0 -2308,0 -2309,0 -2310,0 -2311,0 -2312,0 -2313,0 -2314,0 -2315,0 -2316,0 -2317,0 -2318,0 -2319,0 -2320,0 -2321,0 -2322,0 -2323,0 -2324,0 -2325,0 -2326,0 -2327,0 -2328,0 -2329,0 -2330,0 -2331,0 -2332,0 -2333,0 -2334,0 -2335,0 -2336,0 -2337,0 -2338,0 -2339,0 -2340,0 -2341,0 -2342,0 -2343,0 -2344,0 -2345,0 -2346,0 -2347,0 -2348,0 -2349,0 -2350,0 -2351,0 -2352,0 -2353,0 -2354,0 -2355,0 -2356,0 -2357,0 -2358,0 -2359,0 -2360,0 -2361,0 -2362,0 -2363,0 -2364,0 -2365,0 -2366,0 -2367,0 -2368,0 -2369,0 -2370,0 -2371,0 -2372,0 -2373,0 -2374,0 -2375,0 -2376,0 -2377,0 -2378,0 -2379,0 -2380,0 -2381,0 -2382,0 -2383,0 -2384,0 -2385,0 -2386,0 -2387,0 -2388,0 -2389,0 -2390,0 -2391,0 -2392,0 -2393,0 -2394,0 -2395,0 -2396,0 -2397,0 -2398,0 -2399,0 -2400,0 -2401,0 -2402,0 -2403,0 -2404,0 -2405,0 -2406,0 -2407,0 -2408,0 -2409,0 -2410,0 -2411,0 -2412,0 -2413,0 -2414,0 -2415,0 -2416,0 -2417,0 -2418,0 -2419,0 -2420,0 -2421,0 -2422,0 -2423,0 -2424,0 -2425,0 -2426,0 -2427,0 -2428,0 -2429,0 -2430,0 -2431,0 -2432,0 -2433,0 -2434,0 -2435,0 -2436,0 -2437,0 -2438,0 -2439,0 -2440,0 -2441,0 -2442,0 -2443,0 -2444,0 -2445,0 -2446,0 -2447,0 -2448,0 -2449,0 -2450,0 -2451,0 -2452,0 -2453,0 -2454,0 -2455,0 -2456,0 -2457,0 -2458,0 -2459,0 -2460,0 -2461,0 -2462,0 -2463,0 -2464,0 -2465,0 -2466,0 -2467,0 -2468,0 -2469,0 -2470,0 -2471,0 -2472,0 -2473,0 -2474,0 -2475,0 -2476,0 -2477,0 -2478,0 -2479,0 -2480,0 -2481,0 -2482,0 -2483,0 -2484,0 -2485,0 -2486,0 -2487,0 -2488,0 -2489,0 -2490,0 -2491,0 -2492,0 -2493,0 -2494,0 -2495,0 -2496,0 -2497,0 -2498,0 -2499,0 -2500,0 -2501,0 -2502,0 -2503,0 -2504,0 -2505,0 -2506,0 -2507,0 -2508,0 -2509,0 -2510,0 -2511,0 -2512,0 -2513,0 -2514,0 -2515,0 -2516,0 -2517,0 -2518,0 -2519,0 -2520,0 -2521,0 -2522,0 -2523,0 -2524,0 -2525,0 -2526,0 -2527,0 -2528,0 -2529,0 -2530,0 -2531,0 -2532,0 -2533,0 -2534,0 -2535,0 -2536,0 -2537,0 -2538,0 -2539,0 -2540,0 -2541,0 -2542,0 -2543,0 -2544,0 -2545,0 -2546,0 -2547,0 -2548,0 -2549,0 -2550,0 -2551,0 -2552,0 -2553,0 -2554,0 -2555,0 -2556,0 -2557,0 -2558,0 -2559,0 -2560,0 -2561,0 -2562,0 -2563,0 -2564,0 -2565,0 -2566,0 -2567,0 -2568,0 -2569,0 -2570,0 -2571,0 -2572,0 -2573,0 -2574,0 -2575,0 -2576,0 -2577,0 -2578,0 -2579,0 -2580,0 -2581,0 -2582,0 -2583,0 -2584,0 -2585,0 -2586,0 -2587,0 -2588,0 -2589,0 -2590,0 -2591,0 -2592,0 -2593,0 -2594,0 -2595,0 -2596,0 -2597,0 -2598,0 -2599,0 -2600,0 -2601,0 -2602,0 -2603,0 -2604,0 -2605,0 -2606,0 -2607,0 -2608,0 -2609,0 -2610,0 -2611,0 -2612,0 -2613,0 -2614,0 -2615,0 -2616,0 -2617,0 -2618,0 -2619,0 -2620,0 -2621,0 -2622,0 -2623,0 -2624,0 -2625,0 -2626,0 -2627,0 -2628,0 -2629,0 -2630,0 -2631,0 -2632,0 -2633,0 -2634,0 -2635,0 -2636,0 -2637,0 -2638,0 -2639,0 -2640,0 -2641,0 -2642,0 -2643,0 -2644,0 -2645,0 -2646,0 -2647,0 -2648,0 -2649,0 -2650,0 -2651,0 -2652,0 -2653,0 -2654,0 -2655,0 -2656,0 -2657,0 -2658,0 -2659,0 -2660,0 -2661,0 -2662,0 -2663,0 -2664,0 -2665,0 -2666,0 -2667,0 -2668,0 -2669,0 -2670,0 -2671,0 -2672,0 -2673,0 -2674,0 -2675,0 -2676,0 -2677,0 -2678,0 -2679,0 -2680,0 -2681,0 -2682,0 -2683,0 -2684,0 -2685,0 -2686,0 -2687,0 -2688,0 -2689,0 -2690,0 -2691,0 -2692,0 -2693,0 -2694,0 -2695,0 -2696,0 -2697,0 -2698,0 -2699,0 -2700,0 -2701,0 -2702,0 -2703,0 -2704,0 -2705,0 -2706,0 -2707,0 -2708,0 -2709,0 -2710,0 -2711,0 -2712,0 -2713,0 -2714,0 -2715,0 -2716,0 -2717,0 -2718,0 -2719,0 -2720,0 -2721,0 -2722,0 -2723,0 -2724,0 -2725,0 -2726,0 -2727,0 -2728,0 -2729,0 -2730,0 -2731,0 -2732,0 -2733,0 -2734,0 -2735,0 -2736,0 -2737,0 -2738,0 -2739,0 -2740,0 -2741,0 -2742,0 -2743,0 -2744,0 -2745,0 -2746,0 -2747,0 -2748,0 -2749,0 -2750,0 -2751,0 -2752,0 -2753,0 -2754,0 -2755,0 -2756,0 -2757,0 -2758,0 -2759,0 -2760,0 -2761,0 -2762,0 -2763,0 -2764,0 -2765,0 -2766,0 -2767,0 -2768,0 -2769,0 -2770,0 -2771,0 -2772,0 -2773,0 -2774,0 -2775,0 -2776,0 -2777,0 -2778,0 -2779,0 -2780,0 -2781,0 -2782,0 -2783,0 -2784,0 -2785,0 -2786,0 -2787,0 -2788,0 -2789,0 -2790,0 -2791,0 -2792,0 -2793,0 -2794,0 -2795,0 -2796,0 -2797,0 -2798,0 -2799,0 -2800,0 -2801,0 -2802,0 -2803,0 -2804,0 -2805,0 -2806,0 -2807,0 -2808,0 -2809,0 -2810,0 -2811,0 -2812,0 -2813,0 -2814,0 -2815,0 -2816,0 -2817,0 -2818,0 -2819,0 -2820,0 -2821,0 -2822,0 -2823,0 -2824,0 -2825,0 -2826,0 -2827,0 -2828,0 -2829,0 -2830,0 -2831,0 -2832,0 -2833,0 -2834,0 -2835,0 -2836,0 -2837,0 -2838,0 -2839,0 -2840,0 -2841,0 -2842,0 -2843,0 -2844,0 -2845,0 -2846,0 -2847,0 -2848,0 -2849,0 -2850,0 -2851,0 -2852,0 -2853,0 -2854,0 -2855,0 -2856,0 -2857,0 -2858,0 -2859,0 -2860,0 -2861,0 -2862,0 -2863,0 -2864,0 -2865,0 -2866,0 -2867,0 -2868,0 -2869,0 -2870,0 -2871,0 -2872,0 -2873,0 -2874,0 -2875,0 -2876,0 -2877,0 -2878,0 -2879,0 -2880,0 -2881,0 -2882,0 -2883,0 -2884,0 -2885,0 -2886,0 -2887,0 -2888,0 -2889,0 -2890,0 -2891,0 -2892,0 -2893,0 -2894,0 -2895,0 -2896,0 -2897,0 -2898,0 -2899,0 -2900,0 -2901,0 -2902,0 -2903,0 -2904,0 -2905,0 -2906,0 -2907,0 -2908,0 -2909,0 -2910,0 -2911,0 -2912,0 -2913,0 -2914,0 -2915,0 -2916,0 -2917,0 -2918,0 -2919,0 -2920,0 -2921,0 -2922,0 -2923,0 -2924,0 -2925,0 -2926,0 -2927,0 -2928,0 -2929,0 -2930,0 -2931,0 -2932,0 -2933,0 -2934,0 -2935,0 -2936,0 -2937,0 -2938,0 -2939,0 -2940,0 -2941,0 -2942,0 -2943,0 -2944,0 -2945,0 -2946,0 -2947,0 -2948,0 -2949,0 -2950,0 -2951,0 -2952,0 -2953,0 -2954,0 -2955,0 -2956,0 -2957,0 -2958,0 -2959,0 -2960,0 -2961,0 -2962,0 -2963,0 -2964,0 -2965,0 -2966,0 -2967,0 -2968,0 -2969,0 -2970,0 -2971,0 -2972,0 -2973,0 -2974,0 -2975,0 -2976,0 -2977,0 -2978,0 -2979,0 -2980,0 -2981,0 -2982,0 -2983,0 -2984,0 -2985,0 -2986,0 -2987,0 -2988,0 -2989,0 -2990,0 -2991,0 -2992,0 -2993,0 -2994,0 -2995,0 -2996,0 -2997,0 -2998,0 -2999,0 -3000,0 -3001,0 -3002,0 -3003,0 -3004,0 -3005,0 -3006,0 -3007,0 -3008,0 -3009,0 -3010,0 -3011,0 -3012,0 -3013,0 -3014,0 -3015,0 -3016,0 -3017,0 -3018,0 -3019,0 -3020,0 -3021,0 -3022,0 -3023,0 -3024,0 -3025,0 -3026,0 -3027,0 -3028,0 -3029,0 -3030,0 -3031,0 -3032,0 -3033,0 -3034,0 -3035,0 -3036,0 -3037,0 -3038,0 -3039,0 -3040,0 -3041,0 -3042,0 -3043,0 -3044,0 -3045,0 -3046,0 -3047,0 -3048,0 -3049,0 -3050,0 -3051,0 -3052,0 -3053,0 -3054,0 -3055,0 -3056,0 -3057,0 -3058,0 -3059,0 -3060,0 -3061,0 -3062,0 -3063,0 -3064,0 -3065,0 -3066,0 -3067,0 -3068,0 -3069,0 -3070,0 -3071,0 -3072,0 -3073,0 -3074,0 -3075,0 -3076,0 -3077,0 -3078,0 -3079,0 -3080,0 -3081,0 -3082,0 -3083,0 -3084,0 -3085,0 -3086,0 -3087,0 -3088,0 -3089,0 -3090,0 -3091,0 -3092,0 -3093,0 -3094,0 -3095,0 -3096,0 -3097,0 -3098,0 -3099,0 -3100,0 -3101,0 -3102,0 -3103,0 -3104,0 -3105,0 -3106,0 -3107,0 -3108,0 -3109,0 -3110,0 -3111,0 -3112,0 -3113,0 -3114,0 -3115,0 -3116,0 -3117,0 -3118,0 -3119,0 -3120,0 -3121,0 -3122,0 -3123,0 -3124,0 -3125,0 -3126,0 -3127,0 -3128,0 -3129,0 -3130,0 -3131,0 -3132,0 -3133,0 -3134,0 -3135,0 -3136,0 -3137,0 -3138,0 -3139,0 -3140,0 -3141,0 -3142,0 -3143,0 -3144,0 -3145,0 -3146,0 -3147,0 -3148,0 -3149,0 -3150,0 -3151,0 -3152,0 -3153,0 -3154,0 -3155,0 -3156,0 -3157,0 -3158,0 -3159,0 -3160,0 -3161,0 -3162,0 -3163,0 -3164,0 -3165,0 -3166,0 -3167,0 -3168,0 -3169,0 -3170,0 -3171,0 -3172,0 -3173,0 -3174,0 -3175,0 -3176,0 -3177,0 -3178,0 -3179,0 -3180,0 -3181,0 -3182,0 -3183,0 -3184,0 -3185,0 -3186,0 -3187,0 -3188,0 -3189,0 -3190,0 -3191,0 -3192,0 -3193,0 -3194,0 -3195,0 -3196,0 -3197,0 -3198,0 -3199,0 -3200,0 -3201,0 -3202,0 -3203,0 -3204,0 -3205,0 -3206,0 -3207,0 -3208,0 -3209,0 -3210,0 -3211,0 -3212,0 -3213,0 -3214,0 -3215,0 -3216,0 -3217,0 -3218,0 -3219,0 -3220,0 -3221,0 -3222,0 -3223,0 -3224,0 -3225,0 -3226,0 -3227,0 -3228,0 -3229,0 -3230,0 -3231,0 -3232,0 -3233,0 -3234,0 -3235,0 -3236,0 -3237,0 -3238,0 -3239,0 -3240,0 -3241,0 -3242,0 -3243,0 -3244,0 -3245,0 -3246,0 -3247,0 -3248,0 -3249,0 -3250,0 -3251,0 -3252,0 -3253,0 -3254,0 -3255,0 -3256,0 -3257,0 -3258,0 -3259,0 -3260,0 -3261,0 -3262,0 -3263,0 -3264,0 -3265,0 -3266,0 -3267,0 -3268,0 -3269,0 -3270,0 -3271,0 -3272,0 -3273,0 -3274,0 -3275,0 -3276,0 -3277,0 -3278,0 -3279,0 -3280,0 -3281,0 -3282,0 -3283,0 -3284,0 -3285,0 -3286,0 -3287,0 -3288,0 -3289,0 -3290,0 -3291,0 -3292,0 -3293,0 -3294,0 -3295,0 -3296,0 -3297,0 -3298,0 -3299,0 -3300,0 -3301,0 -3302,0 -3303,0 -3304,0 -3305,0 -3306,0 -3307,0 -3308,0 -3309,0 -3310,0 -3311,0 -3312,0 -3313,0 -3314,0 -3315,0 -3316,0 -3317,0 -3318,0 -3319,0 -3320,0 -3321,0 -3322,0 -3323,0 -3324,0 -3325,0 -3326,0 -3327,0 -3328,0 -3329,0 -3330,0 -3331,0 -3332,0 -3333,0 -3334,0 -3335,0 -3336,0 -3337,0 -3338,0 -3339,0 -3340,0 -3341,0 -3342,0 -3343,0 -3344,0 -3345,0 -3346,0 -3347,0 -3348,0 -3349,0 -3350,0 -3351,0 -3352,0 -3353,0 -3354,0 -3355,0 -3356,0 -3357,0 -3358,0 -3359,0 -3360,0 -3361,0 -3362,0 -3363,0 -3364,0 -3365,0 -3366,0 -3367,0 -3368,0 -3369,0 -3370,0 -3371,0 -3372,0 -3373,0 -3374,0 -3375,0 -3376,0 -3377,0 -3378,0 -3379,0 -3380,0 -3381,0 -3382,0 -3383,0 -3384,0 -3385,0 -3386,0 -3387,0 -3388,0 -3389,0 -3390,0 -3391,0 -3392,0 -3393,0 -3394,0 -3395,0 -3396,0 -3397,0 -3398,0 -3399,0 -3400,0 -3401,0 -3402,0 -3403,0 -3404,0 -3405,0 -3406,0 -3407,0 -3408,0 -3409,0 -3410,0 -3411,0 -3412,0 -3413,0 -3414,0 -3415,0 -3416,0 -3417,0 -3418,0 -3419,0 -3420,0 -3421,0 -3422,0 -3423,0 -3424,0 -3425,0 -3426,0 -3427,0 -3428,0 -3429,0 -3430,0 -3431,0 -3432,0 -3433,0 -3434,0 -3435,0 -3436,0 -3437,0 -3438,0 -3439,0 -3440,0 -3441,0 -3442,0 -3443,0 -3444,0 -3445,0 -3446,0 -3447,0 -3448,0 -3449,0 -3450,0 -3451,0 -3452,0 -3453,0 -3454,0 -3455,0 -3456,0 -3457,0 -3458,0 -3459,0 -3460,0 -3461,0 -3462,0 -3463,0 -3464,0 -3465,0 -3466,0 -3467,0 -3468,0 -3469,0 -3470,0 -3471,0 -3472,0 -3473,0 -3474,0 -3475,0 -3476,0 -3477,0 -3478,0 -3479,0 -3480,0 -3481,0 -3482,0 -3483,0 -3484,0 -3485,0 -3486,0 -3487,0 -3488,0 -3489,0 -3490,0 -3491,0 -3492,0 -3493,0 -3494,0 -3495,0 -3496,0 -3497,0 -3498,0 -3499,0 -3500,0 -3501,0 -3502,0 -3503,0 -3504,0 -3505,0 -3506,0 -3507,0 -3508,0 -3509,0 -3510,0 -3511,0 -3512,0 -3513,0 -3514,0 -3515,0 -3516,0 -3517,0 -3518,0 -3519,0 -3520,0 -3521,0 -3522,0 -3523,0 -3524,0 -3525,0 -3526,0 -3527,0 -3528,0 -3529,0 -3530,0 -3531,0 -3532,0 -3533,0 -3534,0 -3535,0 -3536,0 -3537,0 -3538,0 -3539,0 -3540,0 -3541,0 -3542,0 -3543,0 -3544,0 -3545,0 -3546,0 -3547,0 -3548,0 -3549,0 -3550,0 -3551,0 -3552,0 -3553,0 -3554,0 -3555,0 -3556,0 -3557,0 -3558,0 -3559,0 -3560,0 -3561,0 -3562,0 -3563,0 -3564,0 -3565,0 -3566,0 -3567,0 -3568,0 -3569,0 -3570,0 -3571,0 -3572,0 -3573,0 -3574,0 -3575,0 -3576,0 -3577,0 -3578,0 -3579,0 -3580,0 -3581,0 -3582,0 -3583,0 -3584,0 -3585,0 -3586,0 -3587,0 -3588,0 -3589,0 -3590,0 -3591,0 -3592,0 -3593,0 -3594,0 -3595,0 -3596,0 -3597,0 -3598,0 -3599,0 -3600,0 -3601,0 -3602,0 -3603,0 -3604,0 -3605,0 -3606,0 -3607,0 -3608,0 -3609,0 -3610,0 -3611,0 -3612,0 -3613,0 -3614,0 -3615,0 -3616,0 -3617,0 -3618,0 -3619,0 -3620,0 -3621,0 -3622,0 -3623,0 -3624,0 -3625,0 -3626,0 -3627,0 -3628,0 -3629,0 -3630,0 -3631,0 -3632,0 -3633,0 -3634,0 -3635,0 -3636,0 -3637,0 -3638,0 -3639,0 -3640,0 -3641,0 -3642,0 -3643,0 -3644,0 -3645,0 -3646,0 -3647,0 -3648,0 -3649,0 -3650,0 -3651,0 -3652,0 -3653,0 -3654,0 -3655,0 -3656,0 -3657,0 -3658,0 -3659,0 -3660,0 -3661,0 -3662,0 -3663,0 -3664,0 -3665,0 -3666,0 -3667,0 -3668,0 -3669,0 -3670,0 -3671,0 -3672,0 -3673,0 -3674,0 -3675,0 -3676,0 -3677,0 -3678,0 -3679,0 -3680,0 -3681,0 -3682,0 -3683,0 -3684,0 -3685,0 -3686,0 -3687,0 -3688,0 -3689,0 -3690,0 -3691,0 -3692,0 -3693,0 -3694,0 -3695,0 -3696,0 -3697,0 -3698,0 -3699,0 -3700,0 -3701,0 -3702,0 -3703,0 -3704,0 -3705,0 -3706,0 -3707,0 -3708,0 -3709,0 -3710,0 -3711,0 -3712,0 -3713,0 -3714,0 -3715,0 -3716,0 -3717,0 -3718,0 -3719,0 -3720,0 -3721,0 -3722,0 -3723,0 -3724,0 -3725,0 -3726,0 -3727,0 -3728,0 -3729,0 -3730,0 -3731,0 -3732,0 -3733,0 -3734,0 -3735,0 -3736,0 -3737,0 -3738,0 -3739,0 -3740,0 -3741,0 -3742,0 -3743,0 -3744,0 -3745,0 -3746,0 -3747,0 -3748,0 -3749,0 -3750,0 -3751,0 -3752,0 -3753,0 -3754,0 -3755,0 -3756,0 -3757,0 -3758,0 -3759,0 -3760,0 -3761,0 -3762,0 -3763,0 -3764,0 -3765,0 -3766,0 -3767,0 -3768,0 -3769,0 -3770,0 -3771,0 -3772,0 -3773,0 -3774,0 -3775,0 -3776,0 -3777,0 -3778,0 -3779,0 -3780,0 -3781,0 -3782,0 -3783,0 -3784,0 -3785,0 -3786,0 -3787,0 -3788,0 -3789,0 -3790,0 -3791,0 -3792,0 -3793,0 -3794,0 -3795,0 -3796,0 -3797,0 -3798,0 -3799,0 -3800,0 -3801,0 -3802,0 -3803,0 -3804,0 -3805,0 -3806,0 -3807,0 -3808,0 -3809,0 -3810,0 -3811,0 -3812,0 -3813,0 -3814,0 -3815,0 -3816,0 -3817,0 -3818,0 -3819,0 -3820,0 -3821,0 -3822,0 -3823,0 -3824,0 -3825,0 -3826,0 -3827,0 -3828,0 -3829,0 -3830,0 -3831,0 -3832,0 -3833,0 -3834,0 -3835,0 -3836,0 -3837,0 -3838,0 -3839,0 -3840,0 -3841,0 -3842,0 -3843,0 -3844,0 -3845,0 -3846,0 -3847,0 -3848,0 -3849,0 -3850,0 -3851,0 -3852,0 -3853,0 -3854,0 -3855,0 -3856,0 -3857,0 -3858,0 -3859,0 -3860,0 -3861,0 -3862,0 -3863,0 -3864,0 -3865,0 -3866,0 -3867,0 -3868,0 -3869,0 -3870,0 -3871,0 -3872,0 -3873,0 -3874,0 -3875,0 -3876,0 -3877,0 -3878,0 -3879,0 -3880,0 -3881,0 -3882,0 -3883,0 -3884,0 -3885,0 -3886,0 -3887,0 -3888,0 -3889,0 -3890,0 -3891,0 -3892,0 -3893,0 -3894,0 -3895,0 -3896,0 -3897,0 -3898,0 -3899,0 -3900,0 -3901,0 -3902,0 -3903,0 -3904,0 -3905,0 -3906,0 -3907,0 -3908,0 -3909,0 -3910,0 -3911,0 -3912,0 -3913,0 -3914,0 -3915,0 -3916,0 -3917,0 -3918,0 -3919,0 -3920,0 -3921,0 -3922,0 -3923,0 -3924,0 -3925,0 -3926,0 -3927,0 -3928,0 -3929,0 -3930,0 -3931,0 -3932,0 -3933,0 -3934,0 -3935,0 -3936,0 -3937,0 -3938,0 -3939,0 -3940,0 -3941,0 -3942,0 -3943,0 -3944,0 -3945,0 -3946,0 -3947,0 -3948,0 -3949,0 -3950,0 -3951,0 -3952,0 -3953,0 -3954,0 -3955,0 -3956,0 -3957,0 -3958,0 -3959,0 -3960,0 -3961,0 -3962,0 -3963,0 -3964,0 -3965,0 -3966,0 -3967,0 -3968,0 -3969,0 -3970,0 -3971,0 -3972,0 -3973,0 -3974,0 -3975,0 -3976,0 -3977,0 -3978,0 -3979,0 -3980,0 -3981,0 -3982,0 -3983,0 -3984,0 -3985,0 -3986,0 -3987,0 -3988,0 -3989,0 -3990,0 -3991,0 -3992,0 -3993,0 -3994,0 -3995,0 -3996,0 -3997,0 -3998,0 -3999,0 -4000,0 -4001,0 -4002,0 -4003,0 -4004,0 -4005,0 -4006,0 -4007,0 -4008,0 -4009,0 -4010,0 -4011,0 -4012,0 -4013,0 -4014,0 -4015,0 -4016,0 -4017,0 -4018,0 -4019,0 -4020,0 -4021,0 -4022,0 -4023,0 -4024,0 -4025,0 -4026,0 -4027,0 -4028,0 -4029,0 -4030,0 -4031,0 -4032,0 -4033,0 -4034,0 -4035,0 -4036,0 -4037,0 -4038,0 -4039,0 -4040,0 -4041,0 -4042,0 -4043,0 -4044,0 -4045,0 -4046,0 -4047,0 -4048,0 -4049,0 -4050,0 -4051,0 -4052,0 -4053,0 -4054,0 -4055,0 -4056,0 -4057,0 -4058,0 -4059,0 -4060,0 -4061,0 -4062,0 -4063,0 -4064,0 -4065,0 -4066,0 -4067,0 -4068,0 -4069,0 -4070,0 -4071,0 -4072,0 -4073,0 -4074,0 -4075,0 -4076,0 -4077,0 -4078,0 -4079,0 -4080,0 -4081,0 -4082,0 -4083,0 -4084,0 -4085,0 -4086,0 -4087,0 -4088,0 -4089,0 -4090,0 -4091,0 -4092,0 -4093,0 -4094,0 -4095,0 -4096,0 -4097,0 -4098,0 -4099,0 -4100,0 -4101,0 -4102,0 -4103,0 -4104,0 -4105,0 -4106,0 -4107,0 -4108,0 -4109,0 -4110,0 -4111,0 -4112,0 -4113,0 -4114,0 -4115,0 -4116,0 -4117,0 -4118,0 -4119,0 -4120,0 -4121,0 -4122,0 -4123,0 -4124,0 -4125,0 -4126,0 -4127,0 -4128,0 -4129,0 -4130,0 -4131,0 -4132,0 -4133,0 -4134,0 -4135,0 -4136,0 -4137,0 -4138,0 -4139,0 -4140,0 -4141,0 -4142,0 -4143,0 -4144,0 -4145,0 -4146,0 -4147,0 -4148,0 -4149,0 -4150,0 -4151,0 -4152,0 -4153,0 -4154,0 -4155,0 -4156,0 -4157,0 -4158,0 -4159,0 -4160,0 -4161,0 -4162,0 -4163,0 -4164,0 -4165,0 -4166,0 -4167,0 -4168,0 -4169,0 -4170,0 -4171,0 -4172,0 -4173,0 -4174,0 -4175,0 -4176,0 -4177,0 -4178,0 -4179,0 -4180,0 -4181,0 -4182,0 -4183,0 -4184,0 -4185,0 -4186,0 -4187,0 -4188,0 -4189,0 -4190,0 -4191,0 -4192,0 -4193,0 -4194,0 -4195,0 -4196,0 -4197,0 -4198,0 -4199,0 -4200,0 -4201,0 -4202,0 -4203,0 -4204,0 -4205,0 -4206,0 -4207,0 -4208,0 -4209,0 -4210,0 -4211,0 -4212,0 -4213,0 -4214,0 -4215,0 -4216,0 -4217,0 -4218,0 -4219,0 -4220,0 -4221,0 -4222,0 -4223,0 -4224,0 -4225,0 -4226,0 -4227,0 -4228,0 -4229,0 -4230,0 -4231,0 -4232,0 -4233,0 -4234,0 -4235,0 -4236,0 -4237,0 -4238,0 -4239,0 -4240,0 -4241,0 -4242,0 -4243,0 -4244,0 -4245,0 -4246,0 -4247,0 -4248,0 -4249,0 -4250,0 -4251,0 -4252,0 -4253,0 -4254,0 -4255,0 -4256,0 -4257,0 -4258,0 -4259,0 -4260,0 -4261,0 -4262,0 -4263,0 -4264,0 -4265,0 -4266,0 -4267,0 -4268,0 -4269,0 -4270,0 -4271,0 -4272,0 -4273,0 -4274,0 -4275,0 -4276,0 -4277,0 -4278,0 -4279,0 -4280,0 -4281,0 -4282,0 -4283,0 -4284,0 -4285,0 -4286,0 -4287,0 -4288,0 -4289,0 -4290,0 -4291,0 -4292,0 -4293,0 -4294,0 -4295,0 -4296,0 -4297,0 -4298,0 -4299,0 -4300,0 -4301,0 -4302,0 -4303,0 -4304,0 -4305,0 -4306,0 -4307,0 -4308,0 -4309,0 -4310,0 -4311,0 -4312,0 -4313,0 -4314,0 -4315,0 -4316,0 -4317,0 -4318,0 -4319,0 -4320,0 -4321,0 -4322,0 -4323,0 -4324,0 -4325,0 -4326,0 -4327,0 -4328,0 -4329,0 -4330,0 -4331,0 -4332,0 -4333,0 -4334,0 -4335,0 -4336,0 -4337,0 -4338,0 -4339,0 -4340,0 -4341,0 -4342,0 -4343,0 -4344,0 -4345,0 -4346,0 -4347,0 -4348,0 -4349,0 -4350,0 -4351,0 -4352,0 -4353,0 -4354,0 -4355,0 -4356,0 -4357,0 -4358,0 -4359,0 -4360,0 -4361,0 -4362,0 -4363,0 -4364,0 -4365,0 -4366,0 -4367,0 -4368,0 -4369,0 -4370,0 -4371,0 -4372,0 -4373,0 -4374,0 -4375,0 -4376,0 -4377,0 -4378,0 -4379,0 -4380,0 -4381,0 -4382,0 -4383,0 -4384,0 -4385,0 -4386,0 -4387,0 -4388,0 -4389,0 -4390,0 -4391,0 -4392,0 -4393,0 -4394,0 -4395,0 -4396,0 -4397,0 -4398,0 -4399,0 -4400,0 -4401,0 -4402,0 -4403,0 -4404,0 -4405,0 -4406,0 -4407,0 -4408,0 -4409,0 -4410,0 -4411,0 -4412,0 -4413,0 -4414,0 -4415,0 -4416,0 -4417,0 -4418,0 -4419,0 -4420,0 -4421,0 -4422,0 -4423,0 -4424,0 -4425,0 -4426,0 -4427,0 -4428,0 -4429,0 -4430,0 -4431,0 -4432,0 -4433,0 -4434,0 -4435,0 -4436,0 -4437,0 -4438,0 -4439,0 -4440,0 -4441,0 -4442,0 -4443,0 -4444,0 -4445,0 -4446,0 -4447,0 -4448,0 -4449,0 -4450,0 -4451,0 -4452,0 -4453,0 -4454,0 -4455,0 -4456,0 -4457,0 -4458,0 -4459,0 -4460,0 -4461,0 -4462,0 -4463,0 -4464,0 -4465,0 -4466,0 -4467,0 -4468,0 -4469,0 -4470,0 -4471,0 -4472,0 -4473,0 -4474,0 -4475,0 -4476,0 -4477,0 -4478,0 -4479,0 -4480,0 -4481,0 -4482,0 -4483,0 -4484,0 -4485,0 -4486,0 -4487,0 -4488,0 -4489,0 -4490,0 -4491,0 -4492,0 -4493,0 -4494,0 -4495,0 -4496,0 -4497,0 -4498,0 -4499,0 -4500,0 -4501,0 -4502,0 -4503,0 -4504,0 -4505,0 -4506,0 -4507,0 -4508,0 -4509,0 -4510,0 -4511,0 -4512,0 -4513,0 -4514,0 -4515,0 -4516,0 -4517,0 -4518,0 -4519,0 -4520,0 -4521,0 -4522,0 -4523,0 -4524,0 -4525,0 -4526,0 -4527,0 -4528,0 -4529,0 -4530,0 -4531,0 -4532,0 -4533,0 -4534,0 -4535,0 -4536,0 -4537,0 -4538,0 -4539,0 -4540,0 -4541,0 -4542,0 -4543,0 -4544,0 -4545,0 -4546,0 -4547,0 -4548,0 -4549,0 -4550,0 -4551,0 -4552,0 -4553,0 -4554,0 -4555,0 -4556,0 -4557,0 -4558,0 -4559,0 -4560,0 -4561,0 -4562,0 -4563,0 -4564,0 -4565,0 -4566,0 -4567,0 -4568,0 -4569,0 -4570,0 -4571,0 -4572,0 -4573,0 -4574,0 -4575,0 -4576,0 -4577,0 -4578,0 -4579,0 -4580,0 -4581,0 -4582,0 -4583,0 -4584,0 -4585,0 -4586,0 -4587,0 -4588,0 -4589,0 -4590,0 -4591,0 -4592,0 -4593,0 -4594,0 -4595,0 -4596,0 -4597,0 -4598,0 -4599,0 -4600,0 -4601,0 -4602,0 -4603,0 -4604,0 -4605,0 -4606,0 -4607,0 -4608,0 -4609,0 -4610,0 -4611,0 -4612,0 -4613,0 -4614,0 -4615,0 -4616,0 -4617,0 -4618,0 -4619,0 -4620,0 -4621,0 -4622,0 -4623,0 -4624,0 -4625,0 -4626,0 -4627,0 -4628,0 -4629,0 -4630,0 -4631,0 -4632,0 -4633,0 -4634,0 -4635,0 -4636,0 -4637,0 -4638,0 -4639,0 -4640,0 -4641,0 -4642,0 -4643,0 -4644,0 -4645,0 -4646,0 -4647,0 -4648,0 -4649,0 -4650,0 -4651,0 -4652,0 -4653,0 -4654,0 -4655,0 -4656,0 -4657,0 -4658,0 -4659,0 -4660,0 -4661,0 -4662,0 -4663,0 -4664,0 -4665,0 -4666,0 -4667,0 -4668,0 -4669,0 -4670,0 -4671,0 -4672,0 -4673,0 -4674,0 -4675,0 -4676,0 -4677,0 -4678,0 -4679,0 -4680,0 -4681,0 -4682,0 -4683,0 -4684,0 -4685,0 -4686,0 -4687,0 -4688,0 -4689,0 -4690,0 -4691,0 -4692,0 -4693,0 -4694,0 -4695,0 -4696,0 -4697,0 -4698,0 -4699,0 -4700,0 -4701,0 -4702,0 -4703,0 -4704,0 -4705,0 -4706,0 -4707,0 -4708,0 -4709,0 -4710,0 -4711,0 -4712,0 -4713,0 -4714,0 -4715,0 -4716,0 -4717,0 -4718,0 -4719,0 -4720,0 -4721,0 -4722,0 -4723,0 -4724,0 -4725,0 -4726,0 -4727,0 -4728,0 -4729,0 -4730,0 -4731,0 -4732,0 -4733,0 -4734,0 -4735,0 -4736,0 -4737,0 -4738,0 -4739,0 -4740,0 -4741,0 -4742,0 -4743,0 -4744,0 -4745,0 -4746,0 -4747,0 -4748,0 -4749,0 -4750,0 -4751,0 -4752,0 -4753,0 -4754,0 -4755,0 -4756,0 -4757,0 -4758,0 -4759,0 -4760,0 -4761,0 -4762,0 -4763,0 -4764,0 -4765,0 -4766,0 -4767,0 -4768,0 -4769,0 -4770,0 -4771,0 -4772,0 -4773,0 -4774,0 -4775,0 -4776,0 -4777,0 -4778,0 -4779,0 -4780,0 -4781,0 -4782,0 -4783,0 -4784,0 -4785,0 -4786,0 -4787,0 -4788,0 -4789,0 -4790,0 -4791,0 -4792,0 -4793,0 -4794,0 -4795,0 -4796,0 -4797,0 -4798,0 -4799,0 -4800,0 -4801,0 -4802,0 -4803,0 -4804,0 -4805,0 -4806,0 -4807,0 -4808,0 -4809,0 -4810,0 -4811,0 -4812,0 -4813,0 -4814,0 -4815,0 -4816,0 -4817,0 -4818,0 -4819,0 -4820,0 -4821,0 -4822,0 -4823,0 -4824,0 -4825,0 -4826,0 -4827,0 -4828,0 -4829,0 -4830,0 -4831,0 -4832,0 -4833,0 -4834,0 -4835,0 -4836,0 -4837,0 -4838,0 -4839,0 -4840,0 -4841,0 -4842,0 -4843,0 -4844,0 -4845,0 -4846,0 -4847,0 -4848,0 -4849,0 -4850,0 -4851,0 -4852,0 -4853,0 -4854,0 -4855,0 -4856,0 -4857,0 -4858,0 -4859,0 -4860,0 -4861,0 -4862,0 -4863,0 -4864,0 -4865,0 -4866,0 -4867,0 -4868,0 -4869,0 -4870,0 -4871,0 -4872,0 -4873,0 -4874,0 -4875,0 -4876,0 -4877,0 -4878,0 -4879,0 -4880,0 -4881,0 -4882,0 -4883,0 -4884,0 -4885,0 -4886,0 -4887,0 -4888,0 -4889,0 -4890,0 -4891,0 -4892,0 -4893,0 -4894,0 -4895,0 -4896,0 -4897,0 -4898,0 -4899,0 -4900,0 -4901,0 -4902,0 -4903,0 -4904,0 -4905,0 -4906,0 -4907,0 -4908,0 -4909,0 -4910,0 -4911,0 -4912,0 -4913,0 -4914,0 -4915,0 -4916,0 -4917,0 -4918,0 -4919,0 -4920,0 -4921,0 -4922,0 -4923,0 -4924,0 -4925,0 -4926,0 -4927,0 -4928,0 -4929,0 -4930,0 -4931,0 -4932,0 -4933,0 -4934,0 -4935,0 -4936,0 -4937,0 -4938,0 -4939,0 -4940,0 -4941,0 -4942,0 -4943,0 -4944,0 -4945,0 -4946,0 -4947,0 -4948,0 -4949,0 -4950,0 -4951,0 -4952,0 -4953,0 -4954,0 -4955,0 -4956,0 -4957,0 -4958,0 -4959,0 -4960,0 -4961,0 -4962,0 -4963,0 -4964,0 -4965,0 -4966,0 -4967,0 -4968,0 -4969,0 -4970,0 -4971,0 -4972,0 -4973,0 -4974,0 -4975,0 -4976,0 -4977,0 -4978,0 -4979,0 -4980,0 -4981,0 -4982,0 -4983,0 -4984,0 -4985,0 -4986,0 -4987,0 -4988,0 -4989,0 -4990,0 -4991,0 -4992,0 -4993,0 -4994,0 -4995,0 -4996,0 -4997,0 -4998,0 -4999,0 -5000,0 -5001,0 -5002,0 -5003,0 -5004,0 -5005,0 -5006,0 -5007,0 -5008,0 -5009,0 -5010,0 -5011,0 -5012,0 -5013,0 -5014,0 -5015,0 -5016,0 -5017,0 -5018,0 -5019,0 -5020,0 -5021,0 -5022,0 -5023,0 -5024,0 -5025,0 -5026,0 -5027,0 -5028,0 -5029,0 -5030,0 -5031,0 -5032,0 -5033,0 -5034,0 -5035,0 -5036,0 -5037,0 -5038,0 -5039,0 -5040,0 -5041,0 -5042,0 -5043,0 -5044,0 -5045,0 -5046,0 -5047,0 -5048,0 -5049,0 -5050,0 -5051,0 -5052,0 -5053,0 -5054,0 -5055,0 -5056,0 -5057,0 -5058,0 -5059,0 -5060,0 -5061,0 -5062,0 -5063,0 -5064,0 -5065,0 -5066,0 -5067,0 -5068,0 -5069,0 -5070,0 -5071,0 -5072,0 -5073,0 -5074,0 -5075,0 -5076,0 -5077,0 -5078,0 -5079,0 -5080,0 -5081,0 -5082,0 -5083,0 -5084,0 -5085,0 -5086,0 -5087,0 -5088,0 -5089,0 -5090,0 -5091,0 -5092,0 -5093,0 -5094,0 -5095,0 -5096,0 -5097,0 -5098,0 -5099,0 -5100,0 -5101,0 -5102,0 -5103,0 -5104,0 -5105,0 -5106,0 -5107,0 -5108,0 -5109,0 -5110,0 -5111,0 -5112,0 -5113,0 -5114,0 -5115,0 -5116,0 -5117,0 -5118,0 -5119,0 -5120,0 -5121,0 -5122,0 -5123,0 -5124,0 -5125,0 -5126,0 -5127,0 -5128,0 -5129,0 -5130,0 -5131,0 -5132,0 -5133,0 -5134,0 -5135,0 -5136,0 -5137,0 -5138,0 -5139,0 -5140,0 -5141,0 -5142,0 -5143,0 -5144,0 -5145,0 -5146,0 -5147,0 -5148,0 -5149,0 -5150,0 -5151,0 -5152,0 -5153,0 -5154,0 -5155,0 -5156,0 -5157,0 -5158,0 -5159,0 -5160,0 -5161,0 -5162,0 -5163,0 -5164,0 -5165,0 -5166,0 -5167,0 -5168,0 -5169,0 -5170,0 -5171,0 -5172,0 -5173,0 -5174,0 -5175,0 -5176,0 -5177,0 -5178,0 -5179,0 -5180,0 -5181,0 -5182,0 -5183,0 -5184,0 -5185,0 -5186,0 -5187,0 -5188,0 -5189,0 -5190,0 -5191,0 -5192,0 -5193,0 -5194,0 -5195,0 -5196,0 -5197,0 -5198,0 -5199,0 -5200,0 -5201,0 -5202,0 -5203,0 -5204,0 -5205,0 -5206,0 -5207,0 -5208,0 -5209,0 -5210,0 -5211,0 -5212,0 -5213,0 -5214,0 -5215,0 -5216,0 -5217,0 -5218,0 -5219,0 -5220,0 -5221,0 -5222,0 -5223,0 -5224,0 -5225,0 -5226,0 -5227,0 -5228,0 -5229,0 -5230,0 -5231,0 -5232,0 -5233,0 -5234,0 -5235,0 -5236,0 -5237,0 -5238,0 -5239,0 -5240,0 -5241,0 -5242,0 -5243,0 -5244,0 -5245,0 -5246,0 -5247,0 -5248,0 -5249,0 -5250,0 -5251,0 -5252,0 -5253,0 -5254,0 -5255,0 -5256,0 -5257,0 -5258,0 -5259,0 -5260,0 -5261,0 -5262,0 -5263,0 -5264,0 -5265,0 -5266,0 -5267,0 -5268,0 -5269,0 -5270,0 -5271,0 -5272,0 -5273,0 -5274,0 -5275,0 -5276,0 -5277,0 -5278,0 -5279,0 -5280,0 -5281,0 -5282,0 -5283,0 -5284,0 -5285,0 -5286,0 -5287,0 -5288,0 -5289,0 -5290,0 -5291,0 -5292,0 -5293,0 -5294,0 -5295,0 -5296,0 -5297,0 -5298,0 -5299,0 -5300,0 -5301,0 -5302,0 -5303,0 -5304,0 -5305,0 -5306,0 -5307,0 -5308,0 -5309,0 -5310,0 -5311,0 -5312,0 -5313,0 -5314,0 -5315,0 -5316,0 -5317,0 -5318,0 -5319,0 -5320,0 -5321,0 -5322,0 -5323,0 -5324,0 -5325,0 -5326,0 -5327,0 -5328,0 -5329,0 -5330,0 -5331,0 -5332,0 -5333,0 -5334,0 -5335,0 -5336,0 -5337,0 -5338,0 -5339,0 -5340,0 -5341,0 -5342,0 -5343,0 -5344,0 -5345,0 -5346,0 -5347,0 -5348,0 -5349,0 -5350,0 -5351,0 -5352,0 -5353,0 -5354,0 -5355,0 -5356,0 -5357,0 -5358,0 -5359,0 -5360,0 -5361,0 -5362,0 -5363,0 -5364,0 -5365,0 -5366,0 -5367,0 -5368,0 -5369,0 -5370,0 -5371,0 -5372,0 -5373,0 -5374,0 -5375,0 -5376,0 -5377,0 -5378,0 -5379,0 -5380,0 -5381,0 -5382,0 -5383,0 -5384,0 -5385,0 -5386,0 -5387,0 -5388,0 -5389,0 -5390,0 -5391,0 -5392,0 -5393,0 -5394,0 -5395,0 -5396,0 -5397,0 -5398,0 -5399,0 -5400,0 -5401,0 -5402,0 -5403,0 -5404,0 -5405,0 -5406,0 -5407,0 -5408,0 -5409,0 -5410,0 -5411,0 -5412,0 -5413,0 -5414,0 -5415,0 -5416,0 -5417,0 -5418,0 -5419,0 -5420,0 -5421,0 -5422,0 -5423,0 -5424,0 -5425,0 -5426,0 -5427,0 -5428,0 -5429,0 -5430,0 -5431,0 -5432,0 -5433,0 -5434,0 -5435,0 -5436,0 -5437,0 -5438,0 -5439,0 -5440,0 -5441,0 -5442,0 -5443,0 -5444,0 -5445,0 -5446,0 -5447,0 -5448,0 -5449,0 -5450,0 -5451,0 -5452,0 -5453,0 -5454,0 -5455,0 -5456,0 -5457,0 -5458,0 -5459,0 -5460,0 -5461,0 -5462,0 -5463,0 -5464,0 -5465,0 -5466,0 -5467,0 -5468,0 -5469,0 -5470,0 -5471,0 -5472,0 -5473,0 -5474,0 -5475,0 -5476,0 -5477,0 -5478,0 -5479,0 -5480,0 -5481,0 -5482,0 -5483,0 -5484,0 -5485,0 -5486,0 -5487,0 -5488,0 -5489,0 -5490,0 -5491,0 -5492,0 -5493,0 -5494,0 -5495,0 -5496,0 -5497,0 -5498,0 -5499,0 -5500,0 -5501,0 -5502,0 -5503,0 -5504,0 -5505,0 -5506,0 -5507,0 -5508,0 -5509,0 -5510,0 -5511,0 -5512,0 -5513,0 -5514,0 -5515,0 -5516,0 -5517,0 -5518,0 -5519,0 -5520,0 -5521,0 -5522,0 -5523,0 -5524,0 -5525,0 -5526,0 -5527,0 -5528,0 -5529,0 -5530,0 -5531,0 -5532,0 -5533,0 -5534,0 -5535,0 -5536,0 -5537,0 -5538,0 -5539,0 -5540,0 -5541,0 -5542,0 -5543,0 -5544,0 -5545,0 -5546,0 -5547,0 -5548,0 -5549,0 -5550,0 -5551,0 -5552,0 -5553,0 -5554,0 -5555,0 -5556,0 -5557,0 -5558,0 -5559,0 -5560,0 -5561,0 -5562,0 -5563,0 -5564,0 -5565,0 -5566,0 -5567,0 -5568,0 -5569,0 -5570,0 -5571,0 -5572,0 -5573,0 -5574,0 -5575,0 -5576,0 -5577,0 -5578,0 -5579,0 -5580,0 -5581,0 -5582,0 -5583,0 -5584,0 -5585,0 -5586,0 -5587,0 -5588,0 -5589,0 -5590,0 -5591,0 -5592,0 -5593,0 -5594,0 -5595,0 -5596,0 -5597,0 -5598,0 -5599,0 -5600,0 -5601,0 -5602,0 -5603,0 -5604,0 -5605,0 -5606,0 -5607,0 -5608,0 -5609,0 -5610,0 -5611,0 -5612,0 -5613,0 -5614,0 -5615,0 -5616,0 -5617,0 -5618,0 -5619,0 -5620,0 -5621,0 -5622,0 -5623,0 -5624,0 -5625,0 -5626,0 -5627,0 -5628,0 -5629,0 -5630,0 -5631,0 -5632,0 -5633,0 -5634,0 -5635,0 -5636,0 -5637,0 -5638,0 -5639,0 -5640,0 -5641,0 -5642,0 -5643,0 -5644,0 -5645,0 -5646,0 -5647,0 -5648,0 -5649,0 -5650,0 -5651,0 -5652,0 -5653,0 -5654,0 -5655,0 -5656,0 -5657,0 -5658,0 -5659,0 -5660,0 -5661,0 -5662,0 -5663,0 -5664,0 -5665,0 -5666,0 -5667,0 -5668,0 -5669,0 -5670,0 -5671,0 -5672,0 -5673,0 -5674,0 -5675,0 -5676,0 -5677,0 -5678,0 -5679,0 -5680,0 -5681,0 -5682,0 -5683,0 -5684,0 -5685,0 -5686,0 -5687,0 -5688,0 -5689,0 -5690,0 -5691,0 -5692,0 -5693,0 -5694,0 -5695,0 -5696,0 -5697,0 -5698,0 -5699,0 -5700,0 -5701,0 -5702,0 -5703,0 -5704,0 -5705,0 -5706,0 -5707,0 -5708,0 -5709,0 -5710,0 -5711,0 -5712,0 -5713,0 -5714,0 -5715,0 -5716,0 -5717,0 -5718,0 -5719,0 -5720,0 -5721,0 -5722,0 -5723,0 -5724,0 -5725,0 -5726,0 -5727,0 -5728,0 -5729,0 -5730,0 -5731,0 -5732,0 -5733,0 -5734,0 -5735,0 -5736,0 -5737,0 -5738,0 -5739,0 -5740,0 -5741,0 -5742,0 -5743,0 -5744,0 -5745,0 -5746,0 -5747,0 -5748,0 -5749,0 -5750,0 -5751,0 -5752,0 -5753,0 -5754,0 -5755,0 -5756,0 -5757,0 -5758,0 -5759,0 -5760,0 -5761,0 -5762,0 -5763,0 -5764,0 -5765,0 -5766,0 -5767,0 -5768,0 -5769,0 -5770,0 -5771,0 -5772,0 -5773,0 -5774,0 -5775,0 -5776,0 -5777,0 -5778,0 -5779,0 -5780,0 -5781,0 -5782,0 -5783,0 -5784,0 -5785,0 -5786,0 -5787,0 -5788,0 -5789,0 -5790,0 -5791,0 -5792,0 -5793,0 -5794,0 -5795,0 -5796,0 -5797,0 -5798,0 -5799,0 -5800,0 -5801,0 -5802,0 -5803,0 -5804,0 -5805,0 -5806,0 -5807,0 -5808,0 -5809,0 -5810,0 -5811,0 -5812,0 -5813,0 -5814,0 -5815,0 -5816,0 -5817,0 -5818,0 -5819,0 -5820,0 -5821,0 -5822,0 -5823,0 -5824,0 -5825,0 -5826,0 -5827,0 -5828,0 -5829,0 -5830,0 -5831,0 -5832,0 -5833,0 -5834,0 -5835,0 -5836,0 -5837,0 -5838,0 -5839,0 -5840,0 -5841,0 -5842,0 -5843,0 -5844,0 -5845,0 -5846,0 -5847,0 -5848,0 -5849,0 -5850,0 -5851,0 -5852,0 -5853,0 -5854,0 -5855,0 -5856,0 -5857,0 -5858,0 -5859,0 -5860,0 -5861,0 -5862,0 -5863,0 -5864,0 -5865,0 -5866,0 -5867,0 -5868,0 -5869,0 -5870,0 -5871,0 -5872,0 -5873,0 -5874,0 -5875,0 -5876,0 -5877,0 -5878,0 -5879,0 -5880,0 -5881,0 -5882,0 -5883,0 -5884,0 -5885,0 -5886,0 -5887,0 -5888,0 -5889,0 -5890,0 -5891,0 -5892,0 -5893,0 -5894,0 -5895,0 -5896,0 -5897,0 -5898,0 -5899,0 -5900,0 -5901,0 -5902,0 -5903,0 -5904,0 -5905,0 -5906,0 -5907,0 -5908,0 -5909,0 -5910,0 -5911,0 -5912,0 -5913,0 -5914,0 -5915,0 -5916,0 -5917,0 -5918,0 -5919,0 -5920,0 -5921,0 -5922,0 -5923,0 -5924,0 -5925,0 -5926,0 -5927,0 -5928,0 -5929,0 -5930,0 -5931,0 -5932,0 -5933,0 -5934,0 -5935,0 -5936,0 -5937,0 -5938,0 -5939,0 -5940,0 -5941,0 -5942,0 -5943,0 -5944,0 -5945,0 -5946,0 -5947,0 -5948,0 -5949,0 -5950,0 -5951,0 -5952,0 -5953,0 -5954,0 -5955,0 -5956,0 -5957,0 -5958,0 -5959,0 -5960,0 -5961,0 -5962,0 -5963,0 -5964,0 -5965,0 -5966,0 -5967,0 -5968,0 -5969,0 -5970,0 -5971,0 -5972,0 -5973,0 -5974,0 -5975,0 -5976,0 -5977,0 -5978,0 -5979,0 -5980,0 -5981,0 -5982,0 -5983,0 -5984,0 -5985,0 -5986,0 -5987,0 -5988,0 -5989,0 -5990,0 -5991,0 -5992,0 -5993,0 -5994,0 -5995,0 -5996,0 -5997,0 -5998,0 -5999,0 -6000,0 -6001,0 -6002,0 -6003,0 -6004,0 -6005,0 -6006,0 -6007,0 -6008,0 -6009,0 -6010,0 -6011,0 -6012,0 -6013,0 -6014,0 -6015,0 -6016,0 -6017,0 -6018,0 -6019,0 -6020,0 -6021,0 -6022,0 -6023,0 -6024,0 -6025,0 -6026,0 -6027,0 -6028,0 -6029,0 -6030,0 -6031,0 -6032,0 -6033,0 -6034,0 -6035,0 -6036,0 -6037,0 -6038,0 -6039,0 -6040,0 -6041,0 -6042,0 -6043,0 -6044,0 -6045,0 -6046,0 -6047,0 -6048,0 -6049,0 -6050,0 -6051,0 -6052,0 -6053,0 -6054,0 -6055,0 -6056,0 -6057,0 -6058,0 -6059,0 -6060,0 -6061,0 -6062,0 -6063,0 -6064,0 -6065,0 -6066,0 -6067,0 -6068,0 -6069,0 -6070,0 -6071,0 -6072,0 -6073,0 -6074,0 -6075,0 -6076,0 -6077,0 -6078,0 -6079,0 -6080,0 -6081,0 -6082,0 -6083,0 -6084,0 -6085,0 -6086,0 -6087,0 -6088,0 -6089,0 -6090,0 -6091,0 -6092,0 -6093,0 -6094,0 -6095,0 -6096,0 -6097,0 -6098,0 -6099,0 -6100,0 -6101,0 -6102,0 -6103,0 -6104,0 -6105,0 -6106,0 -6107,0 -6108,0 -6109,0 -6110,0 -6111,0 -6112,0 -6113,0 -6114,0 -6115,0 -6116,0 -6117,0 -6118,0 -6119,0 -6120,0 -6121,0 -6122,0 -6123,0 -6124,0 -6125,0 -6126,0 -6127,0 -6128,0 -6129,0 -6130,0 -6131,0 -6132,0 -6133,0 -6134,0 -6135,0 -6136,0 -6137,0 -6138,0 -6139,0 -6140,0 -6141,0 -6142,0 -6143,0 -6144,0 -6145,0 -6146,0 -6147,0 -6148,0 -6149,0 -6150,0 -6151,0 -6152,0 -6153,0 -6154,0 -6155,0 -6156,0 -6157,0 -6158,0 -6159,0 -6160,0 -6161,0 -6162,0 -6163,0 -6164,0 -6165,0 -6166,0 -6167,0 -6168,0 -6169,0 -6170,0 -6171,0 -6172,0 -6173,0 -6174,0 -6175,0 -6176,0 -6177,0 -6178,0 -6179,0 -6180,0 -6181,0 -6182,0 -6183,0 -6184,0 -6185,0 -6186,0 -6187,0 -6188,0 -6189,0 -6190,0 -6191,0 -6192,0 -6193,0 -6194,0 -6195,0 -6196,0 -6197,0 -6198,0 -6199,0 -6200,0 -6201,0 -6202,0 -6203,0 -6204,0 -6205,0 -6206,0 -6207,0 -6208,0 -6209,0 -6210,0 -6211,0 -6212,0 -6213,0 -6214,0 -6215,0 -6216,0 -6217,0 -6218,0 -6219,0 -6220,0 -6221,0 -6222,0 -6223,0 -6224,0 -6225,0 -6226,0 -6227,0 -6228,0 -6229,0 -6230,0 -6231,0 -6232,0 -6233,0 -6234,0 -6235,0 -6236,0 -6237,0 -6238,0 -6239,0 -6240,0 -6241,0 -6242,0 -6243,0 -6244,0 -6245,0 -6246,0 -6247,0 -6248,0 -6249,0 -6250,0 -6251,0 -6252,0 -6253,0 -6254,0 -6255,0 -6256,0 -6257,0 -6258,0 -6259,0 -6260,0 -6261,0 -6262,0 -6263,0 -6264,0 -6265,0 -6266,0 -6267,0 -6268,0 -6269,0 -6270,0 -6271,0 -6272,0 -6273,0 -6274,0 -6275,0 -6276,0 -6277,0 -6278,0 -6279,0 -6280,0 -6281,0 -6282,0 -6283,0 -6284,0 -6285,0 -6286,0 -6287,0 -6288,0 -6289,0 -6290,0 -6291,0 -6292,0 -6293,0 -6294,0 -6295,0 -6296,0 -6297,0 -6298,0 -6299,0 -6300,0 -6301,0 -6302,0 -6303,0 -6304,0 -6305,0 -6306,0 -6307,0 -6308,0 -6309,0 -6310,0 -6311,0 -6312,0 -6313,0 -6314,0 -6315,0 -6316,0 -6317,0 -6318,0 -6319,0 -6320,0 -6321,0 -6322,0 -6323,0 -6324,0 -6325,0 -6326,0 -6327,0 -6328,0 -6329,0 -6330,0 -6331,0 -6332,0 -6333,0 -6334,0 -6335,0 -6336,0 -6337,0 -6338,0 -6339,0 -6340,0 -6341,0 -6342,0 -6343,0 -6344,0 -6345,0 -6346,0 -6347,0 -6348,0 -6349,0 -6350,0 -6351,0 -6352,0 -6353,0 -6354,0 -6355,0 -6356,0 -6357,0 -6358,0 -6359,0 -6360,0 -6361,0 -6362,0 -6363,0 -6364,0 -6365,0 -6366,0 -6367,0 -6368,0 -6369,0 -6370,0 -6371,0 -6372,0 -6373,0 -6374,0 -6375,0 -6376,0 -6377,0 -6378,0 -6379,0 -6380,0 -6381,0 -6382,0 -6383,0 -6384,0 -6385,0 -6386,0 -6387,0 -6388,0 -6389,0 -6390,0 -6391,0 -6392,0 -6393,0 -6394,0 -6395,0 -6396,0 -6397,0 -6398,0 -6399,0 -6400,0 -6401,0 -6402,0 -6403,0 -6404,0 -6405,0 -6406,0 -6407,0 -6408,0 -6409,0 -6410,0 -6411,0 -6412,0 -6413,0 -6414,0 -6415,0 -6416,0 -6417,0 -6418,0 -6419,0 -6420,0 -6421,0 -6422,0 -6423,0 -6424,0 -6425,0 -6426,0 -6427,0 -6428,0 -6429,0 -6430,0 -6431,0 -6432,0 -6433,0 -6434,0 -6435,0 -6436,0 -6437,0 -6438,0 -6439,0 -6440,0 -6441,0 -6442,0 -6443,0 -6444,0 -6445,0 -6446,0 -6447,0 -6448,0 -6449,0 -6450,0 -6451,0 -6452,0 -6453,0 -6454,0 -6455,0 -6456,0 -6457,0 -6458,0 -6459,0 -6460,0 -6461,0 -6462,0 -6463,0 -6464,0 -6465,0 -6466,0 -6467,0 -6468,0 -6469,0 -6470,0 -6471,0 -6472,0 -6473,0 -6474,0 -6475,0 -6476,0 -6477,0 -6478,0 -6479,0 -6480,0 -6481,0 -6482,0 -6483,0 -6484,0 -6485,0 -6486,0 -6487,0 -6488,0 -6489,0 -6490,0 -6491,0 -6492,0 -6493,0 -6494,0 -6495,0 -6496,0 -6497,0 -6498,0 -6499,0 -6500,0 -6501,0 -6502,0 -6503,0 -6504,0 -6505,0 -6506,0 -6507,0 -6508,0 -6509,0 -6510,0 -6511,0 -6512,0 -6513,0 -6514,0 -6515,0 -6516,0 -6517,0 -6518,0 -6519,0 -6520,0 -6521,0 -6522,0 -6523,0 -6524,0 -6525,0 -6526,0 -6527,0 -6528,0 -6529,0 -6530,0 -6531,0 -6532,0 -6533,0 -6534,0 -6535,0 -6536,0 -6537,0 -6538,0 -6539,0 -6540,0 -6541,0 -6542,0 -6543,0 -6544,0 -6545,0 -6546,0 -6547,0 -6548,0 -6549,0 -6550,0 -6551,0 -6552,0 -6553,0 -6554,0 -6555,0 -6556,0 -6557,0 -6558,0 -6559,0 -6560,0 -6561,0 -6562,0 -6563,0 -6564,0 -6565,0 -6566,0 -6567,0 -6568,0 -6569,0 -6570,0 -6571,0 -6572,0 -6573,0 -6574,0 -6575,0 -6576,0 -6577,0 -6578,0 -6579,0 -6580,0 -6581,0 -6582,0 -6583,0 -6584,0 -6585,0 -6586,0 -6587,0 -6588,0 -6589,0 -6590,0 -6591,0 -6592,0 -6593,0 -6594,0 -6595,0 -6596,0 -6597,0 -6598,0 -6599,0 -6600,0 -6601,0 -6602,0 -6603,0 -6604,0 -6605,0 -6606,0 -6607,0 -6608,0 -6609,0 -6610,0 -6611,0 -6612,0 -6613,0 -6614,0 -6615,0 -6616,0 -6617,0 -6618,0 -6619,0 -6620,0 -6621,0 -6622,0 -6623,0 -6624,0 -6625,0 -6626,0 -6627,0 -6628,0 -6629,0 -6630,0 -6631,0 -6632,0 -6633,0 -6634,0 -6635,0 -6636,0 -6637,0 -6638,0 -6639,0 -6640,0 -6641,0 -6642,0 -6643,0 -6644,0 -6645,0 -6646,0 -6647,0 -6648,0 -6649,0 -6650,0 -6651,0 -6652,0 -6653,0 -6654,0 -6655,0 -6656,0 -6657,0 -6658,0 -6659,0 -6660,0 -6661,0 -6662,0 -6663,0 -6664,0 -6665,0 -6666,0 -6667,0 -6668,0 -6669,0 -6670,0 -6671,0 -6672,0 -6673,0 -6674,0 -6675,0 -6676,0 -6677,0 -6678,0 -6679,0 -6680,0 -6681,0 -6682,0 -6683,0 -6684,0 -6685,0 -6686,0 -6687,0 -6688,0 -6689,0 -6690,0 -6691,0 -6692,0 -6693,0 -6694,0 -6695,0 -6696,0 -6697,0 -6698,0 -6699,0 -6700,0 -6701,0 -6702,0 -6703,0 -6704,0 -6705,0 -6706,0 -6707,0 -6708,0 -6709,0 -6710,0 -6711,0 -6712,0 -6713,0 -6714,0 -6715,0 -6716,0 -6717,0 -6718,0 -6719,0 -6720,0 -6721,0 -6722,0 -6723,0 -6724,0 -6725,0 -6726,0 -6727,0 -6728,0 -6729,0 -6730,0 -6731,0 -6732,0 -6733,0 -6734,0 -6735,0 -6736,0 -6737,0 -6738,0 -6739,0 -6740,0 -6741,0 -6742,0 -6743,0 -6744,0 -6745,0 -6746,0 -6747,0 -6748,0 -6749,0 -6750,0 -6751,0 -6752,0 -6753,0 -6754,0 -6755,0 -6756,0 -6757,0 -6758,0 -6759,0 -6760,0 -6761,0 -6762,0 -6763,0 -6764,0 -6765,0 -6766,0 -6767,0 -6768,0 -6769,0 -6770,0 -6771,0 -6772,0 -6773,0 -6774,0 -6775,0 -6776,0 -6777,0 -6778,0 -6779,0 -6780,0 -6781,0 -6782,0 -6783,0 -6784,0 -6785,0 -6786,0 -6787,0 -6788,0 -6789,0 -6790,0 -6791,0 -6792,0 -6793,0 -6794,0 -6795,0 -6796,0 -6797,0 -6798,0 -6799,0 -6800,0 -6801,0 -6802,0 -6803,0 -6804,0 -6805,0 -6806,0 -6807,0 -6808,0 -6809,0 -6810,0 -6811,0 -6812,0 -6813,0 -6814,0 -6815,0 -6816,0 -6817,0 -6818,0 -6819,0 -6820,0 -6821,0 -6822,0 -6823,0 -6824,0 -6825,0 -6826,0 -6827,0 -6828,0 -6829,0 -6830,0 -6831,0 -6832,0 -6833,0 -6834,0 -6835,0 -6836,0 -6837,0 -6838,0 -6839,0 -6840,0 -6841,0 -6842,0 -6843,0 -6844,0 -6845,0 -6846,0 -6847,0 -6848,0 -6849,0 -6850,0 -6851,0 -6852,0 -6853,0 -6854,0 -6855,0 -6856,0 -6857,0 -6858,0 -6859,0 -6860,0 -6861,0 -6862,0 -6863,0 -6864,0 -6865,0 -6866,0 -6867,0 -6868,0 -6869,0 -6870,0 -6871,0 -6872,0 -6873,0 -6874,0 -6875,0 -6876,0 -6877,0 -6878,0 -6879,0 -6880,0 -6881,0 -6882,0 -6883,0 -6884,0 -6885,0 -6886,0 -6887,0 -6888,0 -6889,0 -6890,0 -6891,0 -6892,0 -6893,0 -6894,0 -6895,0 -6896,0 -6897,0 -6898,0 -6899,0 -6900,0 -6901,0 -6902,0 -6903,0 -6904,0 -6905,0 -6906,0 -6907,0 -6908,0 -6909,0 -6910,0 -6911,0 -6912,0 -6913,0 -6914,0 -6915,0 -6916,0 -6917,0 -6918,0 -6919,0 -6920,0 -6921,0 -6922,0 -6923,0 -6924,0 -6925,0 -6926,0 -6927,0 -6928,0 -6929,0 -6930,0 -6931,0 -6932,0 -6933,0 -6934,0 -6935,0 -6936,0 -6937,0 -6938,0 -6939,0 -6940,0 -6941,0 -6942,0 -6943,0 -6944,0 -6945,0 -6946,0 -6947,0 -6948,0 -6949,0 -6950,0 -6951,0 -6952,0 -6953,0 -6954,0 -6955,0 -6956,0 -6957,0 -6958,0 -6959,0 -6960,0 -6961,0 -6962,0 -6963,0 -6964,0 -6965,0 -6966,0 -6967,0 -6968,0 -6969,0 -6970,0 -6971,0 -6972,0 -6973,0 -6974,0 -6975,0 -6976,0 -6977,0 -6978,0 -6979,0 -6980,0 -6981,0 -6982,0 -6983,0 -6984,0 -6985,0 -6986,0 -6987,0 -6988,0 -6989,0 -6990,0 -6991,0 -6992,0 -6993,0 -6994,0 -6995,0 -6996,0 -6997,0 -6998,0 -6999,0 -7000,0 -7001,0 -7002,0 -7003,0 -7004,0 -7005,0 -7006,0 -7007,0 -7008,0 -7009,0 -7010,0 -7011,0 -7012,0 -7013,0 -7014,0 -7015,0 -7016,0 -7017,0 -7018,0 -7019,0 -7020,0 -7021,0 -7022,0 -7023,0 -7024,0 -7025,0 -7026,0 -7027,0 -7028,0 -7029,0 -7030,0 -7031,0 -7032,0 -7033,0 -7034,0 -7035,0 -7036,0 -7037,0 -7038,0 -7039,0 -7040,0 -7041,0 -7042,0 -7043,0 -7044,0 -7045,0 -7046,0 -7047,0 -7048,0 -7049,0 -7050,0 -7051,0 -7052,0 -7053,0 -7054,0 -7055,0 -7056,0 -7057,0 -7058,0 -7059,0 -7060,0 -7061,0 -7062,0 -7063,0 -7064,0 -7065,0 -7066,0 -7067,0 -7068,0 -7069,0 -7070,0 -7071,0 -7072,0 -7073,0 -7074,0 -7075,0 -7076,0 -7077,0 -7078,0 -7079,0 -7080,0 -7081,0 -7082,0 -7083,0 -7084,0 -7085,0 -7086,0 -7087,0 -7088,0 -7089,0 -7090,0 -7091,0 -7092,0 -7093,0 -7094,0 -7095,0 -7096,0 -7097,0 -7098,0 -7099,0 -7100,0 -7101,0 -7102,0 -7103,0 -7104,0 -7105,0 -7106,0 -7107,0 -7108,0 -7109,0 -7110,0 -7111,0 -7112,0 -7113,0 -7114,0 -7115,0 -7116,0 -7117,0 -7118,0 -7119,0 -7120,0 -7121,0 -7122,0 -7123,0 -7124,0 -7125,0 -7126,0 -7127,0 -7128,0 -7129,0 -7130,0 -7131,0 -7132,0 -7133,0 -7134,0 -7135,0 -7136,0 -7137,0 -7138,0 -7139,0 -7140,0 -7141,0 -7142,0 -7143,0 -7144,0 -7145,0 -7146,0 -7147,0 -7148,0 -7149,0 -7150,0 -7151,0 -7152,0 -7153,0 -7154,0 -7155,0 -7156,0 -7157,0 -7158,0 -7159,0 -7160,0 -7161,0 -7162,0 -7163,0 -7164,0 -7165,0 -7166,0 -7167,0 -7168,0 -7169,0 -7170,0 -7171,0 -7172,0 -7173,0 -7174,0 -7175,0 -7176,0 -7177,0 -7178,0 -7179,0 -7180,0 -7181,0 -7182,0 -7183,0 -7184,0 -7185,0 -7186,0 -7187,0 -7188,0 -7189,0 -7190,0 -7191,0 -7192,0 -7193,0 -7194,0 -7195,0 -7196,0 -7197,0 -7198,0 -7199,0 -7200,0 -7201,0 -7202,0 -7203,0 -7204,0 -7205,0 -7206,0 -7207,0 -7208,0 -7209,0 -7210,0 -7211,0 -7212,0 -7213,0 -7214,0 -7215,0 -7216,0 -7217,0 -7218,0 -7219,0 -7220,0 -7221,0 -7222,0 -7223,0 -7224,0 -7225,0 -7226,0 -7227,0 -7228,0 -7229,0 -7230,0 -7231,0 -7232,0 -7233,0 -7234,0 -7235,0 -7236,0 -7237,0 -7238,0 -7239,0 -7240,0 -7241,0 -7242,0 -7243,0 -7244,0 -7245,0 -7246,0 -7247,0 -7248,0 -7249,0 -7250,0 -7251,0 -7252,0 -7253,0 -7254,0 -7255,0 -7256,0 -7257,0 -7258,0 -7259,0 -7260,0 -7261,0 -7262,0 -7263,0 -7264,0 -7265,0 -7266,0 -7267,0 -7268,0 -7269,0 -7270,0 -7271,0 -7272,0 -7273,0 -7274,0 -7275,0 -7276,0 -7277,0 -7278,0 -7279,0 -7280,0 -7281,0 -7282,0 -7283,0 -7284,0 -7285,0 -7286,0 -7287,0 -7288,0 -7289,0 -7290,0 -7291,0 -7292,0 -7293,0 -7294,0 -7295,0 -7296,0 -7297,0 -7298,0 -7299,0 -7300,0 -7301,0 -7302,0 -7303,0 -7304,0 -7305,0 -7306,0 -7307,0 -7308,0 -7309,0 -7310,0 -7311,0 -7312,0 -7313,0 -7314,0 -7315,0 -7316,0 -7317,0 -7318,0 -7319,0 -7320,0 -7321,0 -7322,0 -7323,0 -7324,0 -7325,0 -7326,0 -7327,0 -7328,0 -7329,0 -7330,0 -7331,0 -7332,0 -7333,0 -7334,0 -7335,0 -7336,0 -7337,0 -7338,0 -7339,0 -7340,0 -7341,0 -7342,0 -7343,0 -7344,0 -7345,0 -7346,0 -7347,0 -7348,0 -7349,0 -7350,0 -7351,0 -7352,0 -7353,0 -7354,0 -7355,0 -7356,0 -7357,0 -7358,0 -7359,0 -7360,0 -7361,0 -7362,0 -7363,0 -7364,0 -7365,0 -7366,0 -7367,0 -7368,0 -7369,0 -7370,0 -7371,0 -7372,0 -7373,0 -7374,0 -7375,0 -7376,0 -7377,0 -7378,0 -7379,0 -7380,0 -7381,0 -7382,0 -7383,0 -7384,0 -7385,0 -7386,0 -7387,0 -7388,0 -7389,0 -7390,0 -7391,0 -7392,0 -7393,0 -7394,0 -7395,0 -7396,0 -7397,0 -7398,0 -7399,0 -7400,0 -7401,0 -7402,0 -7403,0 -7404,0 -7405,0 -7406,0 -7407,0 -7408,0 -7409,0 -7410,0 -7411,0 -7412,0 -7413,0 -7414,0 -7415,0 -7416,0 -7417,0 -7418,0 -7419,0 -7420,0 -7421,0 -7422,0 -7423,0 -7424,0 -7425,0 -7426,0 -7427,0 -7428,0 -7429,0 -7430,0 -7431,0 -7432,0 -7433,0 -7434,0 -7435,0 -7436,0 -7437,0 -7438,0 -7439,0 -7440,0 -7441,0 -7442,0 -7443,0 -7444,0 -7445,0 -7446,0 -7447,0 -7448,0 -7449,0 -7450,0 -7451,0 -7452,0 -7453,0 -7454,0 -7455,0 -7456,0 -7457,0 -7458,0 -7459,0 -7460,0 -7461,0 -7462,0 -7463,0 -7464,0 -7465,0 -7466,0 -7467,0 -7468,0 -7469,0 -7470,0 -7471,0 -7472,0 -7473,0 -7474,0 -7475,0 -7476,0 -7477,0 -7478,0 -7479,0 -7480,0 -7481,0 -7482,0 -7483,0 -7484,0 -7485,0 -7486,0 -7487,0 -7488,0 -7489,0 -7490,0 -7491,0 -7492,0 -7493,0 -7494,0 -7495,0 -7496,0 -7497,0 -7498,0 -7499,0 -7500,0 -7501,0 -7502,0 -7503,0 -7504,0 -7505,0 -7506,0 -7507,0 -7508,0 -7509,0 -7510,0 -7511,0 -7512,0 -7513,0 -7514,0 -7515,0 -7516,0 -7517,0 -7518,0 -7519,0 -7520,0 -7521,0 -7522,0 -7523,0 -7524,0 -7525,0 -7526,0 -7527,0 -7528,0 -7529,0 -7530,0 -7531,0 -7532,0 -7533,0 -7534,0 -7535,0 -7536,0 -7537,0 -7538,0 -7539,0 -7540,0 -7541,0 -7542,0 -7543,0 -7544,0 -7545,0 -7546,0 -7547,0 -7548,0 -7549,0 -7550,0 -7551,0 -7552,0 -7553,0 -7554,0 -7555,0 -7556,0 -7557,0 -7558,0 -7559,0 -7560,0 -7561,0 -7562,0 -7563,0 -7564,0 -7565,0 -7566,0 -7567,0 -7568,0 -7569,0 -7570,0 -7571,0 -7572,0 -7573,0 -7574,0 -7575,0 -7576,0 -7577,0 -7578,0 -7579,0 -7580,0 -7581,0 -7582,0 -7583,0 -7584,0 -7585,0 -7586,0 -7587,0 -7588,0 -7589,0 -7590,0 -7591,0 -7592,0 -7593,0 -7594,0 -7595,0 -7596,0 -7597,0 -7598,0 -7599,0 -7600,0 -7601,0 -7602,0 -7603,0 -7604,0 -7605,0 -7606,0 -7607,0 -7608,0 -7609,0 -7610,0 -7611,0 -7612,0 -7613,0 -7614,0 -7615,0 -7616,0 -7617,0 -7618,0 -7619,0 -7620,0 -7621,0 -7622,0 -7623,0 -7624,0 -7625,0 -7626,0 -7627,0 -7628,0 -7629,0 -7630,0 -7631,0 -7632,0 -7633,0 -7634,0 -7635,0 -7636,0 -7637,0 -7638,0 -7639,0 -7640,0 -7641,0 -7642,0 -7643,0 -7644,0 -7645,0 -7646,0 -7647,0 -7648,0 -7649,0 -7650,0 -7651,0 -7652,0 -7653,0 -7654,0 -7655,0 -7656,0 -7657,0 -7658,0 -7659,0 -7660,0 -7661,0 -7662,0 -7663,0 -7664,0 -7665,0 -7666,0 -7667,0 -7668,0 -7669,0 -7670,0 -7671,0 -7672,0 -7673,0 -7674,0 -7675,0 -7676,0 -7677,0 -7678,0 -7679,0 -7680,0 -7681,0 -7682,0 -7683,0 -7684,0 -7685,0 -7686,0 -7687,0 -7688,0 -7689,0 -7690,0 -7691,0 -7692,0 -7693,0 -7694,0 -7695,0 -7696,0 -7697,0 -7698,0 -7699,0 -7700,0 -7701,0 -7702,0 -7703,0 -7704,0 -7705,0 -7706,0 -7707,0 -7708,0 -7709,0 -7710,0 -7711,0 -7712,0 -7713,0 -7714,0 -7715,0 -7716,0 -7717,0 -7718,0 -7719,0 -7720,0 -7721,0 -7722,0 -7723,0 -7724,0 -7725,0 -7726,0 -7727,0 -7728,0 -7729,0 -7730,0 -7731,0 -7732,0 -7733,0 -7734,0 -7735,0 -7736,0 -7737,0 -7738,0 -7739,0 -7740,0 -7741,0 -7742,0 -7743,0 -7744,0 -7745,0 -7746,0 -7747,0 -7748,0 -7749,0 -7750,0 -7751,0 -7752,0 -7753,0 -7754,0 -7755,0 -7756,0 -7757,0 -7758,0 -7759,0 -7760,0 -7761,0 -7762,0 -7763,0 -7764,0 -7765,0 -7766,0 -7767,0 -7768,0 -7769,0 -7770,0 -7771,0 -7772,0 -7773,0 -7774,0 -7775,0 -7776,0 -7777,0 -7778,0 -7779,0 -7780,0 -7781,0 -7782,0 -7783,0 -7784,0 -7785,0 -7786,0 -7787,0 -7788,0 -7789,0 -7790,0 -7791,0 -7792,0 -7793,0 -7794,0 -7795,0 -7796,0 -7797,0 -7798,0 -7799,0 -7800,0 -7801,0 -7802,0 -7803,0 -7804,0 -7805,0 -7806,0 -7807,0 -7808,0 -7809,0 -7810,0 -7811,0 -7812,0 -7813,0 -7814,0 -7815,0 -7816,0 -7817,0 -7818,0 -7819,0 -7820,0 -7821,0 -7822,0 -7823,0 -7824,0 -7825,0 -7826,0 -7827,0 -7828,0 -7829,0 -7830,0 -7831,0 -7832,0 -7833,0 -7834,0 -7835,0 -7836,0 -7837,0 -7838,0 -7839,0 -7840,0 -7841,0 -7842,0 -7843,0 -7844,0 -7845,0 -7846,0 -7847,0 -7848,0 -7849,0 -7850,0 -7851,0 -7852,0 -7853,0 -7854,0 -7855,0 -7856,0 -7857,0 -7858,0 -7859,0 -7860,0 -7861,0 -7862,0 -7863,0 -7864,0 -7865,0 -7866,0 -7867,0 -7868,0 -7869,0 -7870,0 -7871,0 -7872,0 -7873,0 -7874,0 -7875,0 -7876,0 -7877,0 -7878,0 -7879,0 -7880,0 -7881,0 -7882,0 -7883,0 -7884,0 -7885,0 -7886,0 -7887,0 -7888,0 -7889,0 -7890,0 -7891,0 -7892,0 -7893,0 -7894,0 -7895,0 -7896,0 -7897,0 -7898,0 -7899,0 -7900,0 -7901,0 -7902,0 -7903,0 -7904,0 -7905,0 -7906,0 -7907,0 -7908,0 -7909,0 -7910,0 -7911,0 -7912,0 -7913,0 -7914,0 -7915,0 -7916,0 -7917,0 -7918,0 -7919,0 -7920,0 -7921,0 -7922,0 -7923,0 -7924,0 -7925,0 -7926,0 -7927,0 -7928,0 -7929,0 -7930,0 -7931,0 -7932,0 -7933,0 -7934,0 -7935,0 -7936,0 -7937,0 -7938,0 -7939,0 -7940,0 -7941,0 -7942,0 -7943,0 -7944,0 -7945,0 -7946,0 -7947,0 -7948,0 -7949,0 -7950,0 -7951,0 -7952,0 -7953,0 -7954,0 -7955,0 -7956,0 -7957,0 -7958,0 -7959,0 -7960,0 -7961,0 -7962,0 -7963,0 -7964,0 -7965,0 -7966,0 -7967,0 -7968,0 -7969,0 -7970,0 -7971,0 -7972,0 -7973,0 -7974,0 -7975,0 -7976,0 -7977,0 -7978,0 -7979,0 -7980,0 -7981,0 -7982,0 -7983,0 -7984,0 -7985,0 -7986,0 -7987,0 -7988,0 -7989,0 -7990,0 -7991,0 -7992,0 -7993,0 -7994,0 -7995,0 -7996,0 -7997,0 -7998,0 -7999,0 -8000,0 -8001,0 -8002,0 -8003,0 -8004,0 -8005,0 -8006,0 -8007,0 -8008,0 -8009,0 -8010,0 -8011,0 -8012,0 -8013,0 -8014,0 -8015,0 -8016,0 -8017,0 -8018,0 -8019,0 -8020,0 -8021,0 -8022,0 -8023,0 -8024,0 -8025,0 -8026,0 -8027,0 -8028,0 -8029,0 -8030,0 -8031,0 -8032,0 -8033,0 -8034,0 -8035,0 -8036,0 -8037,0 -8038,0 -8039,0 -8040,0 -8041,0 -8042,0 -8043,0 -8044,0 -8045,0 -8046,0 -8047,0 -8048,0 -8049,0 -8050,0 -8051,0 -8052,0 -8053,0 -8054,0 -8055,0 -8056,0 -8057,0 -8058,0 -8059,0 -8060,0 -8061,0 -8062,0 -8063,0 -8064,0 -8065,0 -8066,0 -8067,0 -8068,0 -8069,0 -8070,0 -8071,0 -8072,0 -8073,0 -8074,0 -8075,0 -8076,0 -8077,0 -8078,0 -8079,0 -8080,0 -8081,0 -8082,0 -8083,0 -8084,0 -8085,0 -8086,0 -8087,0 -8088,0 -8089,0 -8090,0 -8091,0 -8092,0 -8093,0 -8094,0 -8095,0 -8096,0 -8097,0 -8098,0 -8099,0 -8100,0 -8101,0 -8102,0 -8103,0 -8104,0 -8105,0 -8106,0 -8107,0 -8108,0 -8109,0 -8110,0 -8111,0 -8112,0 -8113,0 -8114,0 -8115,0 -8116,0 -8117,0 -8118,0 -8119,0 -8120,0 -8121,0 -8122,0 -8123,0 -8124,0 -8125,0 -8126,0 -8127,0 -8128,0 -8129,0 -8130,0 -8131,0 -8132,0 -8133,0 -8134,0 -8135,0 -8136,0 -8137,0 -8138,0 -8139,0 -8140,0 -8141,0 -8142,0 -8143,0 -8144,0 -8145,0 -8146,0 -8147,0 -8148,0 -8149,0 -8150,0 -8151,0 -8152,0 -8153,0 -8154,0 -8155,0 -8156,0 -8157,0 -8158,0 -8159,0 -8160,0 -8161,0 -8162,0 -8163,0 -8164,0 -8165,0 -8166,0 -8167,0 -8168,0 -8169,0 -8170,0 -8171,0 -8172,0 -8173,0 -8174,0 -8175,0 -8176,0 -8177,0 -8178,0 -8179,0 -8180,0 -8181,0 -8182,0 -8183,0 -8184,0 -8185,0 -8186,0 -8187,0 -8188,0 -8189,0 -8190,0 -8191,0 -8192,0 -8193,0 -8194,0 -8195,0 -8196,0 -8197,0 -8198,0 -8199,0 -8200,0 -8201,0 -8202,0 -8203,0 -8204,0 -8205,0 -8206,0 -8207,0 -8208,0 -8209,0 -8210,0 -8211,0 -8212,0 -8213,0 -8214,0 -8215,0 -8216,0 -8217,0 -8218,0 -8219,0 -8220,0 -8221,0 -8222,0 -8223,0 -8224,0 -8225,0 -8226,0 -8227,0 -8228,0 -8229,0 -8230,0 -8231,0 -8232,0 -8233,0 -8234,0 -8235,0 -8236,0 -8237,0 -8238,0 -8239,0 -8240,0 -8241,0 -8242,0 -8243,0 -8244,0 -8245,0 -8246,0 -8247,0 -8248,0 -8249,0 -8250,0 -8251,0 -8252,0 -8253,0 -8254,0 -8255,0 -8256,0 -8257,0 -8258,0 -8259,0 -8260,0 -8261,0 -8262,0 -8263,0 -8264,0 -8265,0 -8266,0 -8267,0 -8268,0 -8269,0 -8270,0 -8271,0 -8272,0 -8273,0 -8274,0 -8275,0 -8276,0 -8277,0 -8278,0 -8279,0 -8280,0 -8281,0 -8282,0 -8283,0 -8284,0 -8285,0 -8286,0 -8287,0 -8288,0 -8289,0 -8290,0 -8291,0 -8292,0 -8293,0 -8294,0 -8295,0 -8296,0 -8297,0 -8298,0 -8299,0 -8300,0 -8301,0 -8302,0 -8303,0 -8304,0 -8305,0 -8306,0 -8307,0 -8308,0 -8309,0 -8310,0 -8311,0 -8312,0 -8313,0 -8314,0 -8315,0 -8316,0 -8317,0 -8318,0 -8319,0 -8320,0 -8321,0 -8322,0 -8323,0 -8324,0 -8325,0 -8326,0 -8327,0 -8328,0 -8329,0 -8330,0 -8331,0 -8332,0 -8333,0 -8334,0 -8335,0 -8336,0 -8337,0 -8338,0 -8339,0 -8340,0 -8341,0 -8342,0 -8343,0 -8344,0 -8345,0 -8346,0 -8347,0 -8348,0 -8349,0 -8350,0 -8351,0 -8352,0 -8353,0 -8354,0 -8355,0 -8356,0 -8357,0 -8358,0 -8359,0 -8360,0 -8361,0 -8362,0 -8363,0 -8364,0 -8365,0 -8366,0 -8367,0 -8368,0 -8369,0 -8370,0 -8371,0 -8372,0 -8373,0 -8374,0 -8375,0 -8376,0 -8377,0 -8378,0 -8379,0 -8380,0 -8381,0 -8382,0 -8383,0 -8384,0 -8385,0 -8386,0 -8387,0 -8388,0 -8389,0 -8390,0 -8391,0 -8392,0 -8393,0 -8394,0 -8395,0 -8396,0 -8397,0 -8398,0 -8399,0 -8400,0 -8401,0 -8402,0 -8403,0 -8404,0 -8405,0 -8406,0 -8407,0 -8408,0 -8409,0 -8410,0 -8411,0 -8412,0 -8413,0 -8414,0 -8415,0 -8416,0 -8417,0 -8418,0 -8419,0 -8420,0 -8421,0 -8422,0 -8423,0 -8424,0 -8425,0 -8426,0 -8427,0 -8428,0 -8429,0 -8430,0 -8431,0 -8432,0 -8433,0 -8434,0 -8435,0 -8436,0 -8437,0 -8438,0 -8439,0 -8440,0 -8441,0 -8442,0 -8443,0 -8444,0 -8445,0 -8446,0 -8447,0 -8448,0 -8449,0 -8450,0 -8451,0 -8452,0 -8453,0 -8454,0 -8455,0 -8456,0 -8457,0 -8458,0 -8459,0 -8460,0 -8461,0 -8462,0 -8463,0 -8464,0 -8465,0 -8466,0 -8467,0 -8468,0 -8469,0 -8470,0 -8471,0 -8472,0 -8473,0 -8474,0 -8475,0 -8476,0 -8477,0 -8478,0 -8479,0 -8480,0 -8481,0 -8482,0 -8483,0 -8484,0 -8485,0 -8486,0 -8487,0 -8488,0 -8489,0 -8490,0 -8491,0 -8492,0 -8493,0 -8494,0 -8495,0 -8496,0 -8497,0 -8498,0 -8499,0 -8500,0 -8501,0 -8502,0 -8503,0 -8504,0 -8505,0 -8506,0 -8507,0 -8508,0 -8509,0 -8510,0 -8511,0 -8512,0 -8513,0 -8514,0 -8515,0 -8516,0 -8517,0 -8518,0 -8519,0 -8520,0 -8521,0 -8522,0 -8523,0 -8524,0 -8525,0 -8526,0 -8527,0 -8528,0 -8529,0 -8530,0 -8531,0 -8532,0 -8533,0 -8534,0 -8535,0 -8536,0 -8537,0 -8538,0 -8539,0 -8540,0 -8541,0 -8542,0 -8543,0 -8544,0 -8545,0 -8546,0 -8547,0 -8548,0 -8549,0 -8550,0 -8551,0 -8552,0 -8553,0 -8554,0 -8555,0 -8556,0 -8557,0 -8558,0 -8559,0 -8560,0 -8561,0 -8562,0 -8563,0 -8564,0 -8565,0 -8566,0 -8567,0 -8568,0 -8569,0 -8570,0 -8571,0 -8572,0 -8573,0 -8574,0 -8575,0 -8576,0 -8577,0 -8578,0 -8579,0 -8580,0 -8581,0 -8582,0 -8583,0 -8584,0 -8585,0 -8586,0 -8587,0 -8588,0 -8589,0 -8590,0 -8591,0 -8592,0 -8593,0 -8594,0 -8595,0 -8596,0 -8597,0 -8598,0 -8599,0 -8600,0 -8601,0 -8602,0 -8603,0 -8604,0 -8605,0 -8606,0 -8607,0 -8608,0 -8609,0 -8610,0 -8611,0 -8612,0 -8613,0 -8614,0 -8615,0 -8616,0 -8617,0 -8618,0 -8619,0 -8620,0 -8621,0 -8622,0 -8623,0 -8624,0 -8625,0 -8626,0 -8627,0 -8628,0 -8629,0 -8630,0 -8631,0 -8632,0 -8633,0 -8634,0 -8635,0 -8636,0 -8637,0 -8638,0 -8639,0 -8640,0 -8641,0 -8642,0 -8643,0 -8644,0 -8645,0 -8646,0 -8647,0 -8648,0 -8649,0 -8650,0 -8651,0 -8652,0 -8653,0 -8654,0 -8655,0 -8656,0 -8657,0 -8658,0 -8659,0 -8660,0 -8661,0 -8662,0 -8663,0 -8664,0 -8665,0 -8666,0 -8667,0 -8668,0 -8669,0 -8670,0 -8671,0 -8672,0 -8673,0 -8674,0 -8675,0 -8676,0 -8677,0 -8678,0 -8679,0 -8680,0 -8681,0 -8682,0 -8683,0 -8684,0 -8685,0 -8686,0 -8687,0 -8688,0 -8689,0 -8690,0 -8691,0 -8692,0 -8693,0 -8694,0 -8695,0 -8696,0 -8697,0 -8698,0 -8699,0 -8700,0 -8701,0 -8702,0 -8703,0 -8704,0 -8705,0 -8706,0 -8707,0 -8708,0 -8709,0 -8710,0 -8711,0 -8712,0 -8713,0 -8714,0 -8715,0 -8716,0 -8717,0 -8718,0 -8719,0 -8720,0 -8721,0 -8722,0 -8723,0 -8724,0 -8725,0 -8726,0 -8727,0 -8728,0 -8729,0 -8730,0 -8731,0 -8732,0 -8733,0 -8734,0 -8735,0 -8736,0 -8737,0 -8738,0 -8739,0 -8740,0 -8741,0 -8742,0 -8743,0 -8744,0 -8745,0 -8746,0 -8747,0 -8748,0 -8749,0 -8750,0 -8751,0 -8752,0 -8753,0 -8754,0 -8755,0 -8756,0 -8757,0 -8758,0 -8759,0 -8760,0 -8761,0 -8762,0 -8763,0 -8764,0 -8765,0 -8766,0 -8767,0 -8768,0 -8769,0 -8770,0 -8771,0 -8772,0 -8773,0 -8774,0 -8775,0 -8776,0 -8777,0 -8778,0 -8779,0 -8780,0 -8781,0 -8782,0 -8783,0 -8784,0 -8785,0 -8786,0 -8787,0 -8788,0 -8789,0 -8790,0 -8791,0 -8792,0 -8793,0 -8794,0 -8795,0 -8796,0 -8797,0 -8798,0 -8799,0 -8800,0 -8801,0 -8802,0 -8803,0 -8804,0 -8805,0 -8806,0 -8807,0 -8808,0 -8809,0 -8810,0 -8811,0 -8812,0 -8813,0 -8814,0 -8815,0 -8816,0 -8817,0 -8818,0 -8819,0 -8820,0 -8821,0 -8822,0 -8823,0 -8824,0 -8825,0 -8826,0 -8827,0 -8828,0 -8829,0 -8830,0 -8831,0 -8832,0 -8833,0 -8834,0 -8835,0 -8836,0 -8837,0 -8838,0 -8839,0 -8840,0 -8841,0 -8842,0 -8843,0 -8844,0 -8845,0 -8846,0 -8847,0 -8848,0 -8849,0 -8850,0 -8851,0 -8852,0 -8853,0 -8854,0 -8855,0 -8856,0 -8857,0 -8858,0 -8859,0 -8860,0 -8861,0 -8862,0 -8863,0 -8864,0 -8865,0 -8866,0 -8867,0 -8868,0 -8869,0 -8870,0 -8871,0 -8872,0 -8873,0 -8874,0 -8875,0 -8876,0 -8877,0 -8878,0 -8879,0 -8880,0 -8881,0 -8882,0 -8883,0 -8884,0 -8885,0 -8886,0 -8887,0 -8888,0 -8889,0 -8890,0 -8891,0 -8892,0 -8893,0 -8894,0 -8895,0 -8896,0 -8897,0 -8898,0 -8899,0 -8900,0 -8901,0 -8902,0 -8903,0 -8904,0 -8905,0 -8906,0 -8907,0 -8908,0 -8909,0 -8910,0 -8911,0 -8912,0 -8913,0 -8914,0 -8915,0 -8916,0 -8917,0 -8918,0 -8919,0 -8920,0 -8921,0 -8922,0 -8923,0 -8924,0 -8925,0 -8926,0 -8927,0 -8928,0 -8929,0 -8930,0 -8931,0 -8932,0 -8933,0 -8934,0 -8935,0 -8936,0 -8937,0 -8938,0 -8939,0 -8940,0 -8941,0 -8942,0 -8943,0 -8944,0 -8945,0 -8946,0 -8947,0 -8948,0 -8949,0 -8950,0 -8951,0 -8952,0 -8953,0 -8954,0 -8955,0 -8956,0 -8957,0 -8958,0 -8959,0 -8960,0 -8961,0 -8962,0 -8963,0 -8964,0 -8965,0 -8966,0 -8967,0 -8968,0 -8969,0 -8970,0 -8971,0 -8972,0 -8973,0 -8974,0 -8975,0 -8976,0 -8977,0 -8978,0 -8979,0 -8980,0 -8981,0 -8982,0 -8983,0 -8984,0 -8985,0 -8986,0 -8987,0 -8988,0 -8989,0 -8990,0 -8991,0 -8992,0 -8993,0 -8994,0 -8995,0 -8996,0 -8997,0 -8998,0 -8999,0 -9000,0 -9001,0 -9002,0 -9003,0 -9004,0 -9005,0 -9006,0 -9007,0 -9008,0 -9009,0 -9010,0 -9011,0 -9012,0 -9013,0 -9014,0 -9015,0 -9016,0 -9017,0 -9018,0 -9019,0 -9020,0 -9021,0 -9022,0 -9023,0 -9024,0 -9025,0 -9026,0 -9027,0 -9028,0 -9029,0 -9030,0 -9031,0 -9032,0 -9033,0 -9034,0 -9035,0 -9036,0 -9037,0 -9038,0 -9039,0 -9040,0 -9041,0 -9042,0 -9043,0 -9044,0 -9045,0 -9046,0 -9047,0 -9048,0 -9049,0 -9050,0 -9051,0 -9052,0 -9053,0 -9054,0 -9055,0 -9056,0 -9057,0 -9058,0 -9059,0 -9060,0 -9061,0 -9062,0 -9063,0 -9064,0 -9065,0 -9066,0 -9067,0 -9068,0 -9069,0 -9070,0 -9071,0 -9072,0 -9073,0 -9074,0 -9075,0 -9076,0 -9077,0 -9078,0 -9079,0 -9080,0 -9081,0 -9082,0 -9083,0 -9084,0 -9085,0 -9086,0 -9087,0 -9088,0 -9089,0 -9090,0 -9091,0 -9092,0 -9093,0 -9094,0 -9095,0 -9096,0 -9097,0 -9098,0 -9099,0 -9100,0 -9101,0 -9102,0 -9103,0 -9104,0 -9105,0 -9106,0 -9107,0 -9108,0 -9109,0 -9110,0 -9111,0 -9112,0 -9113,0 -9114,0 -9115,0 -9116,0 -9117,0 -9118,0 -9119,0 -9120,0 -9121,0 -9122,0 -9123,0 -9124,0 -9125,0 -9126,0 -9127,0 -9128,0 -9129,0 -9130,0 -9131,0 -9132,0 -9133,0 -9134,0 -9135,0 -9136,0 -9137,0 -9138,0 -9139,0 -9140,0 -9141,0 -9142,0 -9143,0 -9144,0 -9145,0 -9146,0 -9147,0 -9148,0 -9149,0 -9150,0 -9151,0 -9152,0 -9153,0 -9154,0 -9155,0 -9156,0 -9157,0 -9158,0 -9159,0 -9160,0 -9161,0 -9162,0 -9163,0 -9164,0 -9165,0 -9166,0 -9167,0 -9168,0 -9169,0 -9170,0 -9171,0 -9172,0 -9173,0 -9174,0 -9175,0 -9176,0 -9177,0 -9178,0 -9179,0 -9180,0 -9181,0 -9182,0 -9183,0 -9184,0 -9185,0 -9186,0 -9187,0 -9188,0 -9189,0 -9190,0 -9191,0 -9192,0 -9193,0 -9194,0 -9195,0 -9196,0 -9197,0 -9198,0 -9199,0 -9200,0 -9201,0 -9202,0 -9203,0 -9204,0 -9205,0 -9206,0 -9207,0 -9208,0 -9209,0 -9210,0 -9211,0 -9212,0 -9213,0 -9214,0 -9215,0 -9216,0 -9217,0 -9218,0 -9219,0 -9220,0 -9221,0 -9222,0 -9223,0 -9224,0 -9225,0 -9226,0 -9227,0 -9228,0 -9229,0 -9230,0 -9231,0 -9232,0 -9233,0 -9234,0 -9235,0 -9236,0 -9237,0 -9238,0 -9239,0 -9240,0 -9241,0 -9242,0 -9243,0 -9244,0 -9245,0 -9246,0 -9247,0 -9248,0 -9249,0 -9250,0 -9251,0 -9252,0 -9253,0 -9254,0 -9255,0 -9256,0 -9257,0 -9258,0 -9259,0 -9260,0 -9261,0 -9262,0 -9263,0 -9264,0 -9265,0 -9266,0 -9267,0 -9268,0 -9269,0 -9270,0 -9271,0 -9272,0 -9273,0 -9274,0 -9275,0 -9276,0 -9277,0 -9278,0 -9279,0 -9280,0 -9281,0 -9282,0 -9283,0 -9284,0 -9285,0 -9286,0 -9287,0 -9288,0 -9289,0 -9290,0 -9291,0 -9292,0 -9293,0 -9294,0 -9295,0 -9296,0 -9297,0 -9298,0 -9299,0 -9300,0 -9301,0 -9302,0 -9303,0 -9304,0 -9305,0 -9306,0 -9307,0 -9308,0 -9309,0 -9310,0 -9311,0 -9312,0 -9313,0 -9314,0 -9315,0 -9316,0 -9317,0 -9318,0 -9319,0 -9320,0 -9321,0 -9322,0 -9323,0 -9324,0 -9325,0 -9326,0 -9327,0 -9328,0 -9329,0 -9330,0 -9331,0 -9332,0 -9333,0 -9334,0 -9335,0 -9336,0 -9337,0 -9338,0 -9339,0 -9340,0 -9341,0 -9342,0 -9343,0 -9344,0 -9345,0 -9346,0 -9347,0 -9348,0 -9349,0 -9350,0 -9351,0 -9352,0 -9353,0 -9354,0 -9355,0 -9356,0 -9357,0 -9358,0 -9359,0 -9360,0 -9361,0 -9362,0 -9363,0 -9364,0 -9365,0 -9366,0 -9367,0 -9368,0 -9369,0 -9370,0 -9371,0 -9372,0 -9373,0 -9374,0 -9375,0 -9376,0 -9377,0 -9378,0 -9379,0 -9380,0 -9381,0 -9382,0 -9383,0 -9384,0 -9385,0 -9386,0 -9387,0 -9388,0 -9389,0 -9390,0 -9391,0 -9392,0 -9393,0 -9394,0 -9395,0 -9396,0 -9397,0 -9398,0 -9399,0 -9400,0 -9401,0 -9402,0 -9403,0 -9404,0 -9405,0 -9406,0 -9407,0 -9408,0 -9409,0 -9410,0 -9411,0 -9412,0 -9413,0 -9414,0 -9415,0 -9416,0 -9417,0 -9418,0 -9419,0 -9420,0 -9421,0 -9422,0 -9423,0 -9424,0 -9425,0 -9426,0 -9427,0 -9428,0 -9429,0 -9430,0 -9431,0 -9432,0 -9433,0 -9434,0 -9435,0 -9436,0 -9437,0 -9438,0 -9439,0 -9440,0 -9441,0 -9442,0 -9443,0 -9444,0 -9445,0 -9446,0 -9447,0 -9448,0 -9449,0 -9450,0 -9451,0 -9452,0 -9453,0 -9454,0 -9455,0 -9456,0 -9457,0 -9458,0 -9459,0 -9460,0 -9461,0 -9462,0 -9463,0 -9464,0 -9465,0 -9466,0 -9467,0 -9468,0 -9469,0 -9470,0 -9471,0 -9472,0 -9473,0 -9474,0 -9475,0 -9476,0 -9477,0 -9478,0 -9479,0 -9480,0 -9481,0 -9482,0 -9483,0 -9484,0 -9485,0 -9486,0 -9487,0 -9488,0 -9489,0 -9490,0 -9491,0 -9492,0 -9493,0 -9494,0 -9495,0 -9496,0 -9497,0 -9498,0 -9499,0 -9500,0 -9501,0 -9502,0 -9503,0 -9504,0 -9505,0 -9506,0 -9507,0 -9508,0 -9509,0 -9510,0 -9511,0 -9512,0 -9513,0 -9514,0 -9515,0 -9516,0 -9517,0 -9518,0 -9519,0 -9520,0 -9521,0 -9522,0 -9523,0 -9524,0 -9525,0 -9526,0 -9527,0 -9528,0 -9529,0 -9530,0 -9531,0 -9532,0 -9533,0 -9534,0 -9535,0 -9536,0 -9537,0 -9538,0 -9539,0 -9540,0 -9541,0 -9542,0 -9543,0 -9544,0 -9545,0 -9546,0 -9547,0 -9548,0 -9549,0 -9550,0 -9551,0 -9552,0 -9553,0 -9554,0 -9555,0 -9556,0 -9557,0 -9558,0 -9559,0 -9560,0 -9561,0 -9562,0 -9563,0 -9564,0 -9565,0 -9566,0 -9567,0 -9568,0 -9569,0 -9570,0 -9571,0 -9572,0 -9573,0 -9574,0 -9575,0 -9576,0 -9577,0 -9578,0 -9579,0 -9580,0 -9581,0 -9582,0 -9583,0 -9584,0 -9585,0 -9586,0 -9587,0 -9588,0 -9589,0 -9590,0 -9591,0 -9592,0 -9593,0 -9594,0 -9595,0 -9596,0 -9597,0 -9598,0 -9599,0 -9600,0 -9601,0 -9602,0 -9603,0 -9604,0 -9605,0 -9606,0 -9607,0 -9608,0 -9609,0 -9610,0 -9611,0 -9612,0 -9613,0 -9614,0 -9615,0 -9616,0 -9617,0 -9618,0 -9619,0 -9620,0 -9621,0 -9622,0 -9623,0 -9624,0 -9625,0 -9626,0 -9627,0 -9628,0 -9629,0 -9630,0 -9631,0 -9632,0 -9633,0 -9634,0 -9635,0 -9636,0 -9637,0 -9638,0 -9639,0 -9640,0 -9641,0 -9642,0 -9643,0 -9644,0 -9645,0 -9646,0 -9647,0 -9648,0 -9649,0 -9650,0 -9651,0 -9652,0 -9653,0 -9654,0 -9655,0 -9656,0 -9657,0 -9658,0 -9659,0 -9660,0 -9661,0 -9662,0 -9663,0 -9664,0 -9665,0 -9666,0 -9667,0 -9668,0 -9669,0 -9670,0 -9671,0 -9672,0 -9673,0 -9674,0 -9675,0 -9676,0 -9677,0 -9678,0 -9679,0 -9680,0 -9681,0 -9682,0 -9683,0 -9684,0 -9685,0 -9686,0 -9687,0 -9688,0 -9689,0 -9690,0 -9691,0 -9692,0 -9693,0 -9694,0 -9695,0 -9696,0 -9697,0 -9698,0 -9699,0 -9700,0 -9701,0 -9702,0 -9703,0 -9704,0 -9705,0 -9706,0 -9707,0 -9708,0 -9709,0 -9710,0 -9711,0 -9712,0 -9713,0 -9714,0 -9715,0 -9716,0 -9717,0 -9718,0 -9719,0 -9720,0 -9721,0 -9722,0 -9723,0 -9724,0 -9725,0 -9726,0 -9727,0 -9728,0 -9729,0 -9730,0 -9731,0 -9732,0 -9733,0 -9734,0 -9735,0 -9736,0 -9737,0 -9738,0 -9739,0 -9740,0 -9741,0 -9742,0 -9743,0 -9744,0 -9745,0 -9746,0 -9747,0 -9748,0 -9749,0 -9750,0 -9751,0 -9752,0 -9753,0 -9754,0 -9755,0 -9756,0 -9757,0 -9758,0 -9759,0 -9760,0 -9761,0 -9762,0 -9763,0 -9764,0 -9765,0 -9766,0 -9767,0 -9768,0 -9769,0 -9770,0 -9771,0 -9772,0 -9773,0 -9774,0 -9775,0 -9776,0 -9777,0 -9778,0 -9779,0 -9780,0 -9781,0 -9782,0 -9783,0 -9784,0 -9785,0 -9786,0 -9787,0 -9788,0 -9789,0 -9790,0 -9791,0 -9792,0 -9793,0 -9794,0 -9795,0 -9796,0 -9797,0 -9798,0 -9799,0 -9800,0 -9801,0 -9802,0 -9803,0 -9804,0 -9805,0 -9806,0 -9807,0 -9808,0 -9809,0 -9810,0 -9811,0 -9812,0 -9813,0 -9814,0 -9815,0 -9816,0 -9817,0 -9818,0 -9819,0 -9820,0 -9821,0 -9822,0 -9823,0 -9824,0 -9825,0 -9826,0 -9827,0 -9828,0 -9829,0 -9830,0 -9831,0 -9832,0 -9833,0 -9834,0 -9835,0 -9836,0 -9837,0 -9838,0 -9839,0 -9840,0 -9841,0 -9842,0 -9843,0 -9844,0 -9845,0 -9846,0 -9847,0 -9848,0 -9849,0 -9850,0 -9851,0 -9852,0 -9853,0 -9854,0 -9855,0 -9856,0 -9857,0 -9858,0 -9859,0 -9860,0 -9861,0 -9862,0 -9863,0 -9864,0 -9865,0 -9866,0 -9867,0 -9868,0 -9869,0 -9870,0 -9871,0 -9872,0 -9873,0 -9874,0 -9875,0 -9876,0 -9877,0 -9878,0 -9879,0 -9880,0 -9881,0 -9882,0 -9883,0 -9884,0 -9885,0 -9886,0 -9887,0 -9888,0 -9889,0 -9890,0 -9891,0 -9892,0 -9893,0 -9894,0 -9895,0 -9896,0 -9897,0 -9898,0 -9899,0 -9900,0 -9901,0 -9902,0 -9903,0 -9904,0 -9905,0 -9906,0 -9907,0 -9908,0 -9909,0 -9910,0 -9911,0 -9912,0 -9913,0 -9914,0 -9915,0 -9916,0 -9917,0 -9918,0 -9919,0 -9920,0 -9921,0 -9922,0 -9923,0 -9924,0 -9925,0 -9926,0 -9927,0 -9928,0 -9929,0 -9930,0 -9931,0 -9932,0 -9933,0 -9934,0 -9935,0 -9936,0 -9937,0 -9938,0 -9939,0 -9940,0 -9941,0 -9942,0 -9943,0 -9944,0 -9945,0 -9946,0 -9947,0 -9948,0 -9949,0 -9950,0 -9951,0 -9952,0 -9953,0 -9954,0 -9955,0 -9956,0 -9957,0 -9958,0 -9959,0 -9960,0 -9961,0 -9962,0 -9963,0 -9964,0 -9965,0 -9966,0 -9967,0 -9968,0 -9969,0 -9970,0 -9971,0 -9972,0 -9973,0 -9974,0 -9975,0 -9976,0 -9977,0 -9978,0 -9979,0 -9980,0 -9981,0 -9982,0 -9983,0 -9984,0 -9985,0 -9986,0 -9987,0 -9988,0 -9989,0 -9990,0 -9991,0 -9992,0 -9993,0 -9994,0 -9995,0 -9996,0 -9997,0 -9998,0 -9999,0 -10000,0 -10001,0 -10002,0 -10003,0 -10004,0 -10005,0 -10006,0 -10007,0 -10008,0 -10009,0 -10010,0 -10011,0 -10012,0 -10013,0 -10014,0 -10015,0 -10016,0 -10017,0 -10018,0 -10019,0 -10020,0 -10021,0 -10022,0 -10023,0 -10024,0 -10025,0 -10026,0 -10027,0 -10028,0 -10029,0 -10030,0 -10031,0 -10032,0 -10033,0 -10034,0 -10035,0 -10036,0 -10037,0 -10038,0 -10039,0 -10040,0 -10041,0 -10042,0 -10043,0 -10044,0 -10045,0 -10046,0 -10047,0 -10048,0 -10049,0 -10050,0 -10051,0 -10052,0 -10053,0 -10054,0 -10055,0 -10056,0 -10057,0 -10058,0 -10059,0 -10060,0 -10061,0 -10062,0 -10063,0 -10064,0 -10065,0 -10066,0 -10067,0 -10068,0 -10069,0 -10070,0 -10071,0 -10072,0 -10073,0 -10074,0 -10075,0 -10076,0 -10077,0 -10078,0 -10079,0 -10080,0 -10081,0 -10082,0 -10083,0 -10084,0 -10085,0 -10086,0 -10087,0 -10088,0 -10089,0 -10090,0 -10091,0 -10092,0 -10093,0 -10094,0 -10095,0 -10096,0 -10097,0 -10098,0 -10099,0 -10100,0 -10101,0 -10102,0 -10103,0 -10104,0 -10105,0 -10106,0 -10107,0 -10108,0 -10109,0 -10110,0 -10111,0 -10112,0 -10113,0 -10114,0 -10115,0 -10116,0 -10117,0 -10118,0 -10119,0 -10120,0 -10121,0 -10122,0 -10123,0 -10124,0 -10125,0 -10126,0 -10127,0 -10128,0 -10129,0 -10130,0 -10131,0 -10132,0 -10133,0 -10134,0 -10135,0 -10136,0 -10137,0 -10138,0 -10139,0 -10140,0 -10141,0 -10142,0 -10143,0 -10144,0 -10145,0 -10146,0 -10147,0 -10148,0 -10149,0 -10150,0 -10151,0 -10152,0 -10153,0 -10154,0 -10155,0 -10156,0 -10157,0 -10158,0 -10159,0 -10160,0 -10161,0 -10162,0 -10163,0 -10164,0 -10165,0 -10166,0 -10167,0 -10168,0 -10169,0 -10170,0 -10171,0 -10172,0 -10173,0 -10174,0 -10175,0 -10176,0 -10177,0 -10178,0 -10179,0 -10180,0 -10181,0 -10182,0 -10183,0 -10184,0 -10185,0 -10186,0 -10187,0 -10188,0 -10189,0 -10190,0 -10191,0 -10192,0 -10193,0 -10194,0 -10195,0 -10196,0 -10197,0 -10198,0 -10199,0 -10200,0 -10201,0 -10202,0 -10203,0 -10204,0 -10205,0 -10206,0 -10207,0 -10208,0 -10209,0 -10210,0 -10211,0 -10212,0 -10213,0 -10214,0 -10215,0 -10216,0 -10217,0 -10218,0 -10219,0 -10220,0 -10221,0 -10222,0 -10223,0 -10224,0 -10225,0 -10226,0 -10227,0 -10228,0 -10229,0 -10230,0 -10231,0 -10232,0 -10233,0 -10234,0 -10235,0 -10236,0 -10237,0 -10238,0 -10239,0 -10240,0 -10241,0 -10242,0 -10243,0 -10244,0 -10245,0 -10246,0 -10247,0 -10248,0 -10249,0 -10250,0 -10251,0 -10252,0 -10253,0 -10254,0 -10255,0 -10256,0 -10257,0 -10258,0 -10259,0 -10260,0 -10261,0 -10262,0 -10263,0 -10264,0 -10265,0 -10266,0 -10267,0 -10268,0 -10269,0 -10270,0 -10271,0 -10272,0 -10273,0 -10274,0 -10275,0 -10276,0 -10277,0 -10278,0 -10279,0 -10280,0 -10281,0 -10282,0 -10283,0 -10284,0 -10285,0 -10286,0 -10287,0 -10288,0 -10289,0 -10290,0 -10291,0 -10292,0 -10293,0 -10294,0 -10295,0 -10296,0 -10297,0 -10298,0 -10299,0 -10300,0 -10301,0 -10302,0 -10303,0 -10304,0 -10305,0 -10306,0 -10307,0 -10308,0 -10309,0 -10310,0 -10311,0 -10312,0 -10313,0 -10314,0 -10315,0 -10316,0 -10317,0 -10318,0 -10319,0 -10320,0 -10321,0 -10322,0 -10323,0 -10324,0 -10325,0 -10326,0 -10327,0 -10328,0 -10329,0 -10330,0 -10331,0 -10332,0 -10333,0 -10334,0 -10335,0 -10336,0 -10337,0 -10338,0 -10339,0 -10340,0 -10341,0 -10342,0 -10343,0 -10344,0 -10345,0 -10346,0 -10347,0 -10348,0 -10349,0 -10350,0 -10351,0 -10352,0 -10353,0 -10354,0 -10355,0 -10356,0 -10357,0 -10358,0 -10359,0 -10360,0 -10361,0 -10362,0 -10363,0 -10364,0 -10365,0 -10366,0 -10367,0 -10368,0 -10369,0 -10370,0 -10371,0 -10372,0 -10373,0 -10374,0 -10375,0 -10376,0 -10377,0 -10378,0 -10379,0 -10380,0 -10381,0 -10382,0 -10383,0 -10384,0 -10385,0 -10386,0 -10387,0 -10388,0 -10389,0 -10390,0 -10391,0 -10392,0 -10393,0 -10394,0 -10395,0 -10396,0 -10397,0 -10398,0 -10399,0 -10400,0 -10401,0 -10402,0 -10403,0 -10404,0 -10405,0 -10406,0 -10407,0 -10408,0 -10409,0 -10410,0 -10411,0 -10412,0 -10413,0 -10414,0 -10415,0 -10416,0 -10417,0 -10418,0 -10419,0 -10420,0 -10421,0 -10422,0 -10423,0 -10424,0 -10425,0 -10426,0 -10427,0 -10428,0 -10429,0 -10430,0 -10431,0 -10432,0 -10433,0 -10434,0 -10435,0 -10436,0 -10437,0 -10438,0 -10439,0 -10440,0 -10441,0 -10442,0 -10443,0 -10444,0 -10445,0 -10446,0 -10447,0 -10448,0 -10449,0 -10450,0 -10451,0 -10452,0 -10453,0 -10454,0 -10455,0 -10456,0 -10457,0 -10458,0 -10459,0 -10460,0 -10461,0 -10462,0 -10463,0 -10464,0 -10465,0 -10466,0 -10467,0 -10468,0 -10469,0 -10470,0 -10471,0 -10472,0 -10473,0 -10474,0 -10475,0 -10476,0 -10477,0 -10478,0 -10479,0 -10480,0 -10481,0 -10482,0 -10483,0 -10484,0 -10485,0 -10486,0 -10487,0 -10488,0 -10489,0 -10490,0 -10491,0 -10492,0 -10493,0 -10494,0 -10495,0 -10496,0 -10497,0 -10498,0 -10499,0 -10500,0 -10501,0 -10502,0 -10503,0 -10504,0 -10505,0 -10506,0 -10507,0 -10508,0 -10509,0 -10510,0 -10511,0 -10512,0 -10513,0 -10514,0 -10515,0 -10516,0 -10517,0 -10518,0 -10519,0 -10520,0 -10521,0 -10522,0 -10523,0 -10524,0 -10525,0 -10526,0 -10527,0 -10528,0 -10529,0 -10530,0 -10531,0 -10532,0 -10533,0 -10534,0 -10535,0 -10536,0 -10537,0 -10538,0 -10539,0 -10540,0 -10541,0 -10542,0 -10543,0 -10544,0 -10545,0 -10546,0 -10547,0 -10548,0 -10549,0 -10550,0 -10551,0 -10552,0 -10553,0 -10554,0 -10555,0 -10556,0 -10557,0 -10558,0 -10559,0 -10560,0 -10561,0 -10562,0 -10563,0 -10564,0 -10565,0 -10566,0 -10567,0 -10568,0 -10569,0 -10570,0 -10571,0 -10572,0 -10573,0 -10574,0 -10575,0 -10576,0 -10577,0 -10578,0 -10579,0 -10580,0 -10581,0 -10582,0 -10583,0 -10584,0 -10585,0 -10586,0 -10587,0 -10588,0 -10589,0 -10590,0 -10591,0 -10592,0 -10593,0 -10594,0 -10595,0 -10596,0 -10597,0 -10598,0 -10599,0 -10600,0 -10601,0 -10602,0 -10603,0 -10604,0 -10605,0 -10606,0 -10607,0 -10608,0 -10609,0 -10610,0 -10611,0 -10612,0 -10613,0 -10614,0 -10615,0 -10616,0 -10617,0 -10618,0 -10619,0 -10620,0 -10621,0 -10622,0 -10623,0 -10624,0 -10625,0 -10626,0 -10627,0 -10628,0 -10629,0 -10630,0 -10631,0 -10632,0 -10633,0 -10634,0 -10635,0 -10636,0 -10637,0 -10638,0 -10639,0 -10640,0 -10641,0 -10642,0 -10643,0 -10644,0 -10645,0 -10646,0 -10647,0 -10648,0 -10649,0 -10650,0 -10651,0 -10652,0 -10653,0 -10654,0 -10655,0 -10656,0 -10657,0 -10658,0 -10659,0 -10660,0 -10661,0 -10662,0 -10663,0 -10664,0 -10665,0 -10666,0 -10667,0 -10668,0 -10669,0 -10670,0 -10671,0 -10672,0 -10673,0 -10674,0 -10675,0 -10676,0 -10677,0 -10678,0 -10679,0 -10680,0 -10681,0 -10682,0 -10683,0 -10684,0 -10685,0 -10686,0 -10687,0 -10688,0 -10689,0 -10690,0 -10691,0 -10692,0 -10693,0 -10694,0 -10695,0 -10696,0 -10697,0 -10698,0 -10699,0 -10700,0 -10701,0 -10702,0 -10703,0 -10704,0 -10705,0 -10706,0 -10707,0 -10708,0 -10709,0 -10710,0 -10711,0 -10712,0 -10713,0 -10714,0 -10715,0 -10716,0 -10717,0 -10718,0 -10719,0 -10720,0 -10721,0 -10722,0 -10723,0 -10724,0 -10725,0 -10726,0 -10727,0 -10728,0 -10729,0 -10730,0 -10731,0 -10732,0 -10733,0 -10734,0 -10735,0 -10736,0 -10737,0 -10738,0 -10739,0 -10740,0 -10741,0 -10742,0 -10743,0 -10744,0 -10745,0 -10746,0 -10747,0 -10748,0 -10749,0 -10750,0 -10751,0 -10752,0 -10753,0 -10754,0 -10755,0 -10756,0 -10757,0 -10758,0 -10759,0 -10760,0 -10761,0 -10762,0 -10763,0 -10764,0 -10765,0 -10766,0 -10767,0 -10768,0 -10769,0 -10770,0 -10771,0 -10772,0 -10773,0 -10774,0 -10775,0 -10776,0 -10777,0 -10778,0 -10779,0 -10780,0 -10781,0 -10782,0 -10783,0 -10784,0 -10785,0 -10786,0 -10787,0 -10788,0 -10789,0 -10790,0 -10791,0 -10792,0 -10793,0 -10794,0 -10795,0 -10796,0 -10797,0 -10798,0 -10799,0 -10800,0 -10801,0 -10802,0 -10803,0 -10804,0 -10805,0 -10806,0 -10807,0 -10808,0 -10809,0 -10810,0 -10811,0 -10812,0 -10813,0 -10814,0 -10815,0 -10816,0 -10817,0 -10818,0 -10819,0 -10820,0 -10821,0 -10822,0 -10823,0 -10824,0 -10825,0 -10826,0 -10827,0 -10828,0 -10829,0 -10830,0 -10831,0 -10832,0 -10833,0 -10834,0 -10835,0 -10836,0 -10837,0 -10838,0 -10839,0 -10840,0 -10841,0 -10842,0 -10843,0 -10844,0 -10845,0 -10846,0 -10847,0 -10848,0 -10849,0 -10850,0 -10851,0 -10852,0 -10853,0 -10854,0 -10855,0 -10856,0 -10857,0 -10858,0 -10859,0 -10860,0 -10861,0 -10862,0 -10863,0 -10864,0 -10865,0 -10866,0 -10867,0 -10868,0 -10869,0 -10870,0 -10871,0 -10872,0 -10873,0 -10874,0 -10875,0 -10876,0 -10877,0 -10878,0 -10879,0 -10880,0 -10881,0 -10882,0 -10883,0 -10884,0 -10885,0 -10886,0 -10887,0 -10888,0 -10889,0 -10890,0 -10891,0 -10892,0 -10893,0 -10894,0 -10895,0 -10896,0 -10897,0 -10898,0 -10899,0 -10900,0 -10901,0 -10902,0 -10903,0 -10904,0 -10905,0 -10906,0 -10907,0 -10908,0 -10909,0 -10910,0 -10911,0 -10912,0 -10913,0 -10914,0 -10915,0 -10916,0 -10917,0 -10918,0 -10919,0 -10920,0 -10921,0 -10922,0 -10923,0 -10924,0 -10925,0 -10926,0 -10927,0 -10928,0 -10929,0 -10930,0 -10931,0 -10932,0 -10933,0 -10934,0 -10935,0 -10936,0 -10937,0 -10938,0 -10939,0 -10940,0 -10941,0 -10942,0 -10943,0 -10944,0 -10945,0 -10946,0 -10947,0 -10948,0 -10949,0 -10950,0 -10951,0 -10952,0 -10953,0 -10954,0 -10955,0 -10956,0 -10957,0 -10958,0 -10959,0 -10960,0 -10961,0 -10962,0 -10963,0 -10964,0 -10965,0 -10966,0 -10967,0 -10968,0 -10969,0 -10970,0 -10971,0 -10972,0 -10973,0 -10974,0 -10975,0 -10976,0 -10977,0 -10978,0 -10979,0 -10980,0 -10981,0 -10982,0 -10983,0 -10984,0 -10985,0 -10986,0 -10987,0 -10988,0 -10989,0 -10990,0 -10991,0 -10992,0 -10993,0 -10994,0 -10995,0 -10996,0 -10997,0 -10998,0 -10999,0 -11000,0 -11001,0 -11002,0 -11003,0 -11004,0 -11005,0 -11006,0 -11007,0 -11008,0 -11009,0 -11010,0 -11011,0 -11012,0 -11013,0 -11014,0 -11015,0 -11016,0 -11017,0 -11018,0 -11019,0 -11020,0 -11021,0 -11022,0 -11023,0 -11024,0 -11025,0 -11026,0 -11027,0 -11028,0 -11029,0 -11030,0 -11031,0 -11032,0 -11033,0 -11034,0 -11035,0 -11036,0 -11037,0 -11038,0 -11039,0 -11040,0 -11041,0 -11042,0 -11043,0 -11044,0 -11045,0 -11046,0 -11047,0 -11048,0 -11049,0 -11050,0 -11051,0 -11052,0 -11053,0 -11054,0 -11055,0 -11056,0 -11057,0 -11058,0 -11059,0 -11060,0 -11061,0 -11062,0 -11063,0 -11064,0 -11065,0 -11066,0 -11067,0 -11068,0 -11069,0 -11070,0 -11071,0 -11072,0 -11073,0 -11074,0 -11075,0 -11076,0 -11077,0 -11078,0 -11079,0 -11080,0 -11081,0 -11082,0 -11083,0 -11084,0 -11085,0 -11086,0 -11087,0 -11088,0 -11089,0 -11090,0 -11091,0 -11092,0 -11093,0 -11094,0 -11095,0 -11096,0 -11097,0 -11098,0 -11099,0 -11100,0 -11101,0 -11102,0 -11103,0 -11104,0 -11105,0 -11106,0 -11107,0 -11108,0 -11109,0 -11110,0 -11111,0 -11112,0 -11113,0 -11114,0 -11115,0 -11116,0 -11117,0 -11118,0 -11119,0 -11120,0 -11121,0 -11122,0 -11123,0 -11124,0 -11125,0 -11126,0 -11127,0 -11128,0 -11129,0 -11130,0 -11131,0 -11132,0 -11133,0 -11134,0 -11135,0 -11136,0 -11137,0 -11138,0 -11139,0 -11140,0 -11141,0 -11142,0 -11143,0 -11144,0 -11145,0 -11146,0 -11147,0 -11148,0 -11149,0 -11150,0 -11151,0 -11152,0 -11153,0 -11154,0 -11155,0 -11156,0 -11157,0 -11158,0 -11159,0 -11160,0 -11161,0 -11162,0 -11163,0 -11164,0 -11165,0 -11166,0 -11167,0 -11168,0 -11169,0 -11170,0 -11171,0 -11172,0 -11173,0 -11174,0 -11175,0 -11176,0 -11177,0 -11178,0 -11179,0 -11180,0 -11181,0 -11182,0 -11183,0 -11184,0 -11185,0 -11186,0 -11187,0 -11188,0 -11189,0 -11190,0 -11191,0 -11192,0 -11193,0 -11194,0 -11195,0 -11196,0 -11197,0 -11198,0 -11199,0 -11200,0 -11201,0 -11202,0 -11203,0 -11204,0 -11205,0 -11206,0 -11207,0 -11208,0 -11209,0 -11210,0 -11211,0 -11212,0 -11213,0 -11214,0 -11215,0 -11216,0 -11217,0 -11218,0 -11219,0 -11220,0 -11221,0 -11222,0 -11223,0 -11224,0 -11225,0 -11226,0 -11227,0 -11228,0 -11229,0 -11230,0 -11231,0 -11232,0 -11233,0 -11234,0 -11235,0 -11236,0 -11237,0 -11238,0 -11239,0 -11240,0 -11241,0 -11242,0 -11243,0 -11244,0 -11245,0 -11246,0 -11247,0 -11248,0 -11249,0 -11250,0 -11251,0 -11252,0 -11253,0 -11254,0 -11255,0 -11256,0 -11257,0 -11258,0 -11259,0 -11260,0 -11261,0 -11262,0 -11263,0 -11264,0 -11265,0 -11266,0 -11267,0 -11268,0 -11269,0 -11270,0 -11271,0 -11272,0 -11273,0 -11274,0 -11275,0 -11276,0 -11277,0 -11278,0 -11279,0 -11280,0 -11281,0 -11282,0 -11283,0 -11284,0 -11285,0 -11286,0 -11287,0 -11288,0 -11289,0 -11290,0 -11291,0 -11292,0 -11293,0 -11294,0 -11295,0 -11296,0 -11297,0 -11298,0 -11299,0 -11300,0 -11301,0 -11302,0 -11303,0 -11304,0 -11305,0 -11306,0 -11307,0 -11308,0 -11309,0 -11310,0 -11311,0 -11312,0 -11313,0 -11314,0 -11315,0 -11316,0 -11317,0 -11318,0 -11319,0 -11320,0 -11321,0 -11322,0 -11323,0 -11324,0 -11325,0 -11326,0 -11327,0 -11328,0 -11329,0 -11330,0 -11331,0 -11332,0 -11333,0 -11334,0 -11335,0 -11336,0 -11337,0 -11338,0 -11339,0 -11340,0 -11341,0 -11342,0 -11343,0 -11344,0 -11345,0 -11346,0 -11347,0 -11348,0 -11349,0 -11350,0 -11351,0 -11352,0 -11353,0 -11354,0 -11355,0 -11356,0 -11357,0 -11358,0 -11359,0 -11360,0 -11361,0 -11362,0 -11363,0 -11364,0 -11365,0 -11366,0 -11367,0 -11368,0 -11369,0 -11370,0 -11371,0 -11372,0 -11373,0 -11374,0 -11375,0 -11376,0 -11377,0 -11378,0 -11379,0 -11380,0 -11381,0 -11382,0 -11383,0 -11384,0 -11385,0 -11386,0 -11387,0 -11388,0 -11389,0 -11390,0 -11391,0 -11392,0 -11393,0 -11394,0 -11395,0 -11396,0 -11397,0 -11398,0 -11399,0 -11400,0 -11401,0 -11402,0 -11403,0 -11404,0 -11405,0 -11406,0 -11407,0 -11408,0 -11409,0 -11410,0 -11411,0 -11412,0 -11413,0 -11414,0 -11415,0 -11416,0 -11417,0 -11418,0 -11419,0 -11420,0 -11421,0 -11422,0 -11423,0 -11424,0 -11425,0 -11426,0 -11427,0 -11428,0 -11429,0 -11430,0 -11431,0 -11432,0 -11433,0 -11434,0 -11435,0 -11436,0 -11437,0 -11438,0 -11439,0 -11440,0 -11441,0 -11442,0 -11443,0 -11444,0 -11445,0 -11446,0 -11447,0 -11448,0 -11449,0 -11450,0 -11451,0 -11452,0 -11453,0 -11454,0 -11455,0 -11456,0 -11457,0 -11458,0 -11459,0 -11460,0 -11461,0 -11462,0 -11463,0 -11464,0 -11465,0 -11466,0 -11467,0 -11468,0 -11469,0 -11470,0 -11471,0 -11472,0 -11473,0 -11474,0 -11475,0 -11476,0 -11477,0 -11478,0 -11479,0 -11480,0 -11481,0 -11482,0 -11483,0 -11484,0 -11485,0 -11486,0 -11487,0 -11488,0 -11489,0 -11490,0 -11491,0 -11492,0 -11493,0 -11494,0 -11495,0 -11496,0 -11497,0 -11498,0 -11499,0 -11500,0 -11501,0 -11502,0 -11503,0 -11504,0 -11505,0 -11506,0 -11507,0 -11508,0 -11509,0 -11510,0 -11511,0 -11512,0 -11513,0 -11514,0 -11515,0 -11516,0 -11517,0 -11518,0 -11519,0 -11520,0 -11521,0 -11522,0 -11523,0 -11524,0 -11525,0 -11526,0 -11527,0 -11528,0 -11529,0 -11530,0 -11531,0 -11532,0 -11533,0 -11534,0 -11535,0 -11536,0 -11537,0 -11538,0 -11539,0 -11540,0 -11541,0 -11542,0 -11543,0 -11544,0 -11545,0 -11546,0 -11547,0 -11548,0 -11549,0 -11550,0 -11551,0 -11552,0 -11553,0 -11554,0 -11555,0 -11556,0 -11557,0 -11558,0 -11559,0 -11560,0 -11561,0 -11562,0 -11563,0 -11564,0 -11565,0 -11566,0 -11567,0 -11568,0 -11569,0 -11570,0 -11571,0 -11572,0 -11573,0 -11574,0 -11575,0 -11576,0 -11577,0 -11578,0 -11579,0 -11580,0 -11581,0 -11582,0 -11583,0 -11584,0 -11585,0 -11586,0 -11587,0 -11588,0 -11589,0 -11590,0 -11591,0 -11592,0 -11593,0 -11594,0 -11595,0 -11596,0 -11597,0 -11598,0 -11599,0 -11600,0 -11601,0 -11602,0 -11603,0 -11604,0 -11605,0 -11606,0 -11607,0 -11608,0 -11609,0 -11610,0 -11611,0 -11612,0 -11613,0 -11614,0 -11615,0 -11616,0 -11617,0 -11618,0 -11619,0 -11620,0 -11621,0 -11622,0 -11623,0 -11624,0 -11625,0 -11626,0 -11627,0 -11628,0 -11629,0 -11630,0 -11631,0 -11632,0 -11633,0 -11634,0 -11635,0 -11636,0 -11637,0 -11638,0 -11639,0 -11640,0 -11641,0 -11642,0 -11643,0 -11644,0 -11645,0 -11646,0 -11647,0 -11648,0 -11649,0 -11650,0 -11651,0 -11652,0 -11653,0 -11654,0 -11655,0 -11656,0 -11657,0 -11658,0 -11659,0 -11660,0 -11661,0 -11662,0 -11663,0 -11664,0 -11665,0 -11666,0 -11667,0 -11668,0 -11669,0 -11670,0 -11671,0 -11672,0 -11673,0 -11674,0 -11675,0 -11676,0 -11677,0 -11678,0 -11679,0 -11680,0 -11681,0 -11682,0 -11683,0 -11684,0 -11685,0 -11686,0 -11687,0 -11688,0 -11689,0 -11690,0 -11691,0 -11692,0 -11693,0 -11694,0 -11695,0 -11696,0 -11697,0 -11698,0 -11699,0 -11700,0 -11701,0 -11702,0 -11703,0 -11704,0 -11705,0 -11706,0 -11707,0 -11708,0 -11709,0 -11710,0 -11711,0 -11712,0 -11713,0 -11714,0 -11715,0 -11716,0 -11717,0 -11718,0 -11719,0 -11720,0 -11721,0 -11722,0 -11723,0 -11724,0 -11725,0 -11726,0 -11727,0 -11728,0 -11729,0 -11730,0 -11731,0 -11732,0 -11733,0 -11734,0 -11735,0 -11736,0 -11737,0 -11738,0 -11739,0 -11740,0 -11741,0 -11742,0 -11743,0 -11744,0 -11745,0 -11746,0 -11747,0 -11748,0 -11749,0 -11750,0 -11751,0 -11752,0 -11753,0 -11754,0 -11755,0 -11756,0 -11757,0 -11758,0 -11759,0 -11760,0 -11761,0 -11762,0 -11763,0 -11764,0 -11765,0 -11766,0 -11767,0 -11768,0 -11769,0 -11770,0 -11771,0 -11772,0 -11773,0 -11774,0 -11775,0 -11776,0 -11777,0 -11778,0 -11779,0 -11780,0 -11781,0 -11782,0 -11783,0 -11784,0 -11785,0 -11786,0 -11787,0 -11788,0 -11789,0 -11790,0 -11791,0 -11792,0 -11793,0 -11794,0 -11795,0 -11796,0 -11797,0 -11798,0 -11799,0 -11800,0 -11801,0 -11802,0 -11803,0 -11804,0 -11805,0 -11806,0 -11807,0 -11808,0 -11809,0 -11810,0 -11811,0 -11812,0 -11813,0 -11814,0 -11815,0 -11816,0 -11817,0 -11818,0 -11819,0 -11820,0 -11821,0 -11822,0 -11823,0 -11824,0 -11825,0 -11826,0 -11827,0 -11828,0 -11829,0 -11830,0 -11831,0 -11832,0 -11833,0 -11834,0 -11835,0 -11836,0 -11837,0 -11838,0 -11839,0 -11840,0 -11841,0 -11842,0 -11843,0 -11844,0 -11845,0 -11846,0 -11847,0 -11848,0 -11849,0 -11850,0 -11851,0 -11852,0 -11853,0 -11854,0 -11855,0 -11856,0 -11857,0 -11858,0 -11859,0 -11860,0 -11861,0 -11862,0 -11863,0 -11864,0 -11865,0 -11866,0 -11867,0 -11868,0 -11869,0 -11870,0 -11871,0 -11872,0 -11873,0 -11874,0 -11875,0 -11876,0 -11877,0 -11878,0 -11879,0 -11880,0 -11881,0 -11882,0 -11883,0 -11884,0 -11885,0 -11886,0 -11887,0 -11888,0 -11889,0 -11890,0 -11891,0 -11892,0 -11893,0 -11894,0 -11895,0 -11896,0 -11897,0 -11898,0 -11899,0 -11900,0 -11901,0 -11902,0 -11903,0 -11904,0 -11905,0 -11906,0 -11907,0 -11908,0 -11909,0 -11910,0 -11911,0 -11912,0 -11913,0 -11914,0 -11915,0 -11916,0 -11917,0 -11918,0 -11919,0 -11920,0 -11921,0 -11922,0 -11923,0 -11924,0 -11925,0 -11926,0 -11927,0 -11928,0 -11929,0 -11930,0 -11931,0 -11932,0 -11933,0 -11934,0 -11935,0 -11936,0 -11937,0 -11938,0 -11939,0 -11940,0 -11941,0 -11942,0 -11943,0 -11944,0 -11945,0 -11946,0 -11947,0 -11948,0 -11949,0 -11950,0 -11951,0 -11952,0 -11953,0 -11954,0 -11955,0 -11956,0 -11957,0 -11958,0 -11959,0 -11960,0 -11961,0 -11962,0 -11963,0 -11964,0 -11965,0 -11966,0 -11967,0 -11968,0 -11969,0 -11970,0 -11971,0 -11972,0 -11973,0 -11974,0 -11975,0 -11976,0 -11977,0 -11978,0 -11979,0 -11980,0 -11981,0 -11982,0 -11983,0 -11984,0 -11985,0 -11986,0 -11987,0 -11988,0 -11989,0 -11990,0 -11991,0 -11992,0 -11993,0 -11994,0 -11995,0 -11996,0 -11997,0 -11998,0 -11999,0 -12000,0 -12001,0 -12002,0 -12003,0 -12004,0 -12005,0 -12006,0 -12007,0 -12008,0 -12009,0 -12010,0 -12011,0 -12012,0 -12013,0 -12014,0 -12015,0 -12016,0 -12017,0 -12018,0 -12019,0 -12020,0 -12021,0 -12022,0 -12023,0 -12024,0 -12025,0 -12026,0 -12027,0 -12028,0 -12029,0 -12030,0 -12031,0 -12032,0 -12033,0 -12034,0 -12035,0 -12036,0 -12037,0 -12038,0 -12039,0 -12040,0 -12041,0 -12042,0 -12043,0 -12044,0 -12045,0 -12046,0 -12047,0 -12048,0 -12049,0 -12050,0 -12051,0 -12052,0 -12053,0 -12054,0 -12055,0 -12056,0 -12057,0 -12058,0 -12059,0 -12060,0 -12061,0 -12062,0 -12063,0 -12064,0 -12065,0 -12066,0 -12067,0 -12068,0 -12069,0 -12070,0 -12071,0 -12072,0 -12073,0 -12074,0 -12075,0 -12076,0 -12077,0 -12078,0 -12079,0 -12080,0 -12081,0 -12082,0 -12083,0 -12084,0 -12085,0 -12086,0 -12087,0 -12088,0 -12089,0 -12090,0 -12091,0 -12092,0 -12093,0 -12094,0 -12095,0 -12096,0 -12097,0 -12098,0 -12099,0 -12100,0 -12101,0 -12102,0 -12103,0 -12104,0 -12105,0 -12106,0 -12107,0 -12108,0 -12109,0 -12110,0 -12111,0 -12112,0 -12113,0 -12114,0 -12115,0 -12116,0 -12117,0 -12118,0 -12119,0 -12120,0 -12121,0 -12122,0 -12123,0 -12124,0 -12125,0 -12126,0 -12127,0 -12128,0 -12129,0 -12130,0 -12131,0 -12132,0 -12133,0 -12134,0 -12135,0 -12136,0 -12137,0 -12138,0 -12139,0 -12140,0 -12141,0 -12142,0 -12143,0 -12144,0 -12145,0 -12146,0 -12147,0 -12148,0 -12149,0 -12150,0 -12151,0 -12152,0 -12153,0 -12154,0 -12155,0 -12156,0 -12157,0 -12158,0 -12159,0 -12160,0 -12161,0 -12162,0 -12163,0 -12164,0 -12165,0 -12166,0 -12167,0 -12168,0 -12169,0 -12170,0 -12171,0 -12172,0 -12173,0 -12174,0 -12175,0 -12176,0 -12177,0 -12178,0 -12179,0 -12180,0 -12181,0 -12182,0 -12183,0 -12184,0 -12185,0 -12186,0 -12187,0 -12188,0 -12189,0 -12190,0 -12191,0 -12192,0 -12193,0 -12194,0 -12195,0 -12196,0 -12197,0 -12198,0 -12199,0 -12200,0 -12201,0 -12202,0 -12203,0 -12204,0 -12205,0 -12206,0 -12207,0 -12208,0 -12209,0 -12210,0 -12211,0 -12212,0 -12213,0 -12214,0 -12215,0 -12216,0 -12217,0 -12218,0 -12219,0 -12220,0 -12221,0 -12222,0 -12223,0 -12224,0 -12225,0 -12226,0 -12227,0 -12228,0 -12229,0 -12230,0 -12231,0 -12232,0 -12233,0 -12234,0 -12235,0 -12236,0 -12237,0 -12238,0 -12239,0 -12240,0 -12241,0 -12242,0 -12243,0 -12244,0 -12245,0 -12246,0 -12247,0 -12248,0 -12249,0 -12250,0 -12251,0 -12252,0 -12253,0 -12254,0 -12255,0 -12256,0 -12257,0 -12258,0 -12259,0 -12260,0 -12261,0 -12262,0 -12263,0 -12264,0 -12265,0 -12266,0 -12267,0 -12268,0 -12269,0 -12270,0 -12271,0 -12272,0 -12273,0 -12274,0 -12275,0 -12276,0 -12277,0 -12278,0 -12279,0 -12280,0 -12281,0 -12282,0 -12283,0 -12284,0 -12285,0 -12286,0 -12287,0 -12288,0 -12289,0 -12290,0 -12291,0 -12292,0 -12293,0 -12294,0 -12295,0 -12296,0 -12297,0 -12298,0 -12299,0 -12300,0 -12301,0 -12302,0 -12303,0 -12304,0 -12305,0 -12306,0 -12307,0 -12308,0 -12309,0 -12310,0 -12311,0 -12312,0 -12313,0 -12314,0 -12315,0 -12316,0 -12317,0 -12318,0 -12319,0 -12320,0 -12321,0 -12322,0 -12323,0 -12324,0 -12325,0 -12326,0 -12327,0 -12328,0 -12329,0 -12330,0 -12331,0 -12332,0 -12333,0 -12334,0 -12335,0 -12336,0 -12337,0 -12338,0 -12339,0 -12340,0 -12341,0 -12342,0 -12343,0 -12344,0 -12345,0 -12346,0 -12347,0 -12348,0 -12349,0 -12350,0 -12351,0 -12352,0 -12353,0 -12354,0 -12355,0 -12356,0 -12357,0 -12358,0 -12359,0 -12360,0 -12361,0 -12362,0 -12363,0 -12364,0 -12365,0 -12366,0 -12367,0 -12368,0 -12369,0 -12370,0 -12371,0 -12372,0 -12373,0 -12374,0 -12375,0 -12376,0 -12377,0 -12378,0 -12379,0 -12380,0 -12381,0 -12382,0 -12383,0 -12384,0 -12385,0 -12386,0 -12387,0 -12388,0 -12389,0 -12390,0 -12391,0 -12392,0 -12393,0 -12394,0 -12395,0 -12396,0 -12397,0 -12398,0 -12399,0 -12400,0 -12401,0 -12402,0 -12403,0 -12404,0 -12405,0 -12406,0 -12407,0 -12408,0 -12409,0 -12410,0 -12411,0 -12412,0 -12413,0 -12414,0 -12415,0 -12416,0 -12417,0 -12418,0 -12419,0 -12420,0 -12421,0 -12422,0 -12423,0 -12424,0 -12425,0 -12426,0 -12427,0 -12428,0 -12429,0 -12430,0 -12431,0 -12432,0 -12433,0 -12434,0 -12435,0 -12436,0 -12437,0 -12438,0 -12439,0 -12440,0 -12441,0 -12442,0 -12443,0 -12444,0 -12445,0 -12446,0 -12447,0 -12448,0 -12449,0 -12450,0 -12451,0 -12452,0 -12453,0 -12454,0 -12455,0 -12456,0 -12457,0 -12458,0 -12459,0 -12460,0 -12461,0 -12462,0 -12463,0 -12464,0 -12465,0 -12466,0 -12467,0 -12468,0 -12469,0 -12470,0 -12471,0 -12472,0 -12473,0 -12474,0 -12475,0 -12476,0 -12477,0 -12478,0 -12479,0 -12480,0 -12481,0 -12482,0 -12483,0 -12484,0 -12485,0 -12486,0 -12487,0 -12488,0 -12489,0 -12490,0 -12491,0 -12492,0 -12493,0 -12494,0 -12495,0 -12496,0 -12497,0 -12498,0 -12499,0 -12500,0 -12501,0 -12502,0 -12503,0 -12504,0 -12505,0 -12506,0 -12507,0 -12508,0 -12509,0 -12510,0 -12511,0 -12512,0 -12513,0 -12514,0 -12515,0 -12516,0 -12517,0 -12518,0 -12519,0 -12520,0 -12521,0 -12522,0 -12523,0 -12524,0 -12525,0 -12526,0 -12527,0 -12528,0 -12529,0 -12530,0 -12531,0 -12532,0 -12533,0 -12534,0 -12535,0 -12536,0 -12537,0 -12538,0 -12539,0 -12540,0 -12541,0 -12542,0 -12543,0 -12544,0 -12545,0 -12546,0 -12547,0 -12548,0 -12549,0 -12550,0 -12551,0 -12552,0 -12553,0 -12554,0 -12555,0 -12556,0 -12557,0 -12558,0 -12559,0 -12560,0 -12561,0 -12562,0 -12563,0 -12564,0 -12565,0 -12566,0 -12567,0 -12568,0 -12569,0 -12570,0 -12571,0 -12572,0 -12573,0 -12574,0 -12575,0 -12576,0 -12577,0 -12578,0 -12579,0 -12580,0 -12581,0 -12582,0 -12583,0 -12584,0 -12585,0 -12586,0 -12587,0 -12588,0 -12589,0 -12590,0 -12591,0 -12592,0 -12593,0 -12594,0 -12595,0 -12596,0 -12597,0 -12598,0 -12599,0 -12600,0 -12601,0 -12602,0 -12603,0 -12604,0 -12605,0 -12606,0 -12607,0 -12608,0 -12609,0 -12610,0 -12611,0 -12612,0 -12613,0 -12614,0 -12615,0 -12616,0 -12617,0 -12618,0 -12619,0 -12620,0 -12621,0 -12622,0 -12623,0 -12624,0 -12625,0 -12626,0 -12627,0 -12628,0 -12629,0 -12630,0 -12631,0 -12632,0 -12633,0 -12634,0 -12635,0 -12636,0 -12637,0 -12638,0 -12639,0 -12640,0 -12641,0 -12642,0 -12643,0 -12644,0 -12645,0 -12646,0 -12647,0 -12648,0 -12649,0 -12650,0 -12651,0 -12652,0 -12653,0 -12654,0 -12655,0 -12656,0 -12657,0 -12658,0 -12659,0 -12660,0 -12661,0 -12662,0 -12663,0 -12664,0 -12665,0 -12666,0 -12667,0 -12668,0 -12669,0 -12670,0 -12671,0 -12672,0 -12673,0 -12674,0 -12675,0 -12676,0 -12677,0 -12678,0 -12679,0 -12680,0 -12681,0 -12682,0 -12683,0 -12684,0 -12685,0 -12686,0 -12687,0 -12688,0 -12689,0 -12690,0 -12691,0 -12692,0 -12693,0 -12694,0 -12695,0 -12696,0 -12697,0 -12698,0 -12699,0 -12700,0 -12701,0 -12702,0 -12703,0 -12704,0 -12705,0 -12706,0 -12707,0 -12708,0 -12709,0 -12710,0 -12711,0 -12712,0 -12713,0 -12714,0 -12715,0 -12716,0 -12717,0 -12718,0 -12719,0 -12720,0 -12721,0 -12722,0 -12723,0 -12724,0 -12725,0 -12726,0 -12727,0 -12728,0 -12729,0 -12730,0 -12731,0 -12732,0 -12733,0 -12734,0 -12735,0 -12736,0 -12737,0 -12738,0 -12739,0 -12740,0 -12741,0 -12742,0 -12743,0 -12744,0 -12745,0 -12746,0 -12747,0 -12748,0 -12749,0 -12750,0 -12751,0 -12752,0 -12753,0 -12754,0 -12755,0 -12756,0 -12757,0 -12758,0 -12759,0 -12760,0 -12761,0 -12762,0 -12763,0 -12764,0 -12765,0 -12766,0 -12767,0 -12768,0 -12769,0 -12770,0 -12771,0 -12772,0 -12773,0 -12774,0 -12775,0 -12776,0 -12777,0 -12778,0 -12779,0 -12780,0 -12781,0 -12782,0 -12783,0 -12784,0 -12785,0 -12786,0 -12787,0 -12788,0 -12789,0 -12790,0 -12791,0 -12792,0 -12793,0 -12794,0 -12795,0 -12796,0 -12797,0 -12798,0 -12799,0 -12800,0 -12801,0 -12802,0 -12803,0 -12804,0 -12805,0 -12806,0 -12807,0 -12808,0 -12809,0 -12810,0 -12811,0 -12812,0 -12813,0 -12814,0 -12815,0 -12816,0 -12817,0 -12818,0 -12819,0 -12820,0 -12821,0 -12822,0 -12823,0 -12824,0 -12825,0 -12826,0 -12827,0 -12828,0 -12829,0 -12830,0 -12831,0 -12832,0 -12833,0 -12834,0 -12835,0 -12836,0 -12837,0 -12838,0 -12839,0 -12840,0 -12841,0 -12842,0 -12843,0 -12844,0 -12845,0 -12846,0 -12847,0 -12848,0 -12849,0 -12850,0 -12851,0 -12852,0 -12853,0 -12854,0 -12855,0 -12856,0 -12857,0 -12858,0 -12859,0 -12860,0 -12861,0 -12862,0 -12863,0 -12864,0 -12865,0 -12866,0 -12867,0 -12868,0 -12869,0 -12870,0 -12871,0 -12872,0 -12873,0 -12874,0 -12875,0 -12876,0 -12877,0 -12878,0 -12879,0 -12880,0 -12881,0 -12882,0 -12883,0 -12884,0 -12885,0 -12886,0 -12887,0 -12888,0 -12889,0 -12890,0 -12891,0 -12892,0 -12893,0 -12894,0 -12895,0 -12896,0 -12897,0 -12898,0 -12899,0 -12900,0 -12901,0 -12902,0 -12903,0 -12904,0 -12905,0 -12906,0 -12907,0 -12908,0 -12909,0 -12910,0 -12911,0 -12912,0 -12913,0 -12914,0 -12915,0 -12916,0 -12917,0 -12918,0 -12919,0 -12920,0 -12921,0 -12922,0 -12923,0 -12924,0 -12925,0 -12926,0 -12927,0 -12928,0 -12929,0 -12930,0 -12931,0 -12932,0 -12933,0 -12934,0 -12935,0 -12936,0 -12937,0 -12938,0 -12939,0 -12940,0 -12941,0 -12942,0 -12943,0 -12944,0 -12945,0 -12946,0 -12947,0 -12948,0 -12949,0 -12950,0 -12951,0 -12952,0 -12953,0 -12954,0 -12955,0 -12956,0 -12957,0 -12958,0 -12959,0 -12960,0 -12961,0 -12962,0 -12963,0 -12964,0 -12965,0 -12966,0 -12967,0 -12968,0 -12969,0 -12970,0 -12971,0 -12972,0 -12973,0 -12974,0 -12975,0 -12976,0 -12977,0 -12978,0 -12979,0 -12980,0 -12981,0 -12982,0 -12983,0 -12984,0 -12985,0 -12986,0 -12987,0 -12988,0 -12989,0 -12990,0 -12991,0 -12992,0 -12993,0 -12994,0 -12995,0 -12996,0 -12997,0 -12998,0 -12999,0 -13000,0 -13001,0 -13002,0 -13003,0 -13004,0 -13005,0 -13006,0 -13007,0 -13008,0 -13009,0 -13010,0 -13011,0 -13012,0 -13013,0 -13014,0 -13015,0 -13016,0 -13017,0 -13018,0 -13019,0 -13020,0 -13021,0 -13022,0 -13023,0 -13024,0 -13025,0 -13026,0 -13027,0 -13028,0 -13029,0 -13030,0 -13031,0 -13032,0 -13033,0 -13034,0 -13035,0 -13036,0 -13037,0 -13038,0 -13039,0 -13040,0 -13041,0 -13042,0 -13043,0 -13044,0 -13045,0 -13046,0 -13047,0 -13048,0 -13049,0 -13050,0 -13051,0 -13052,0 -13053,0 -13054,0 -13055,0 -13056,0 -13057,0 -13058,0 -13059,0 -13060,0 -13061,0 -13062,0 -13063,0 -13064,0 -13065,0 -13066,0 -13067,0 -13068,0 -13069,0 -13070,0 -13071,0 -13072,0 -13073,0 -13074,0 -13075,0 -13076,0 -13077,0 -13078,0 -13079,0 -13080,0 -13081,0 -13082,0 -13083,0 -13084,0 -13085,0 -13086,0 -13087,0 -13088,0 -13089,0 -13090,0 -13091,0 -13092,0 -13093,0 -13094,0 -13095,0 -13096,0 -13097,0 -13098,0 -13099,0 -13100,0 -13101,0 -13102,0 -13103,0 -13104,0 -13105,0 -13106,0 -13107,0 -13108,0 -13109,0 -13110,0 -13111,0 -13112,0 -13113,0 -13114,0 -13115,0 -13116,0 -13117,0 -13118,0 -13119,0 -13120,0 -13121,0 -13122,0 -13123,0 -13124,0 -13125,0 -13126,0 -13127,0 -13128,0 -13129,0 -13130,0 -13131,0 -13132,0 -13133,0 -13134,0 -13135,0 -13136,0 -13137,0 -13138,0 -13139,0 -13140,0 -13141,0 -13142,0 -13143,0 -13144,0 -13145,0 -13146,0 -13147,0 -13148,0 -13149,0 -13150,0 -13151,0 -13152,0 -13153,0 -13154,0 -13155,0 -13156,0 -13157,0 -13158,0 -13159,0 -13160,0 -13161,0 -13162,0 -13163,0 -13164,0 -13165,0 -13166,0 -13167,0 -13168,0 -13169,0 -13170,0 -13171,0 -13172,0 -13173,0 -13174,0 -13175,0 -13176,0 -13177,0 -13178,0 -13179,0 -13180,0 -13181,0 -13182,0 -13183,0 -13184,0 -13185,0 -13186,0 -13187,0 -13188,0 -13189,0 -13190,0 -13191,0 -13192,0 -13193,0 -13194,0 -13195,0 -13196,0 -13197,0 -13198,0 -13199,0 -13200,0 -13201,0 -13202,0 -13203,0 -13204,0 -13205,0 -13206,0 -13207,0 -13208,0 -13209,0 -13210,0 -13211,0 -13212,0 -13213,0 -13214,0 -13215,0 -13216,0 -13217,0 -13218,0 -13219,0 -13220,0 -13221,0 -13222,0 -13223,0 -13224,0 -13225,0 -13226,0 -13227,0 -13228,0 -13229,0 -13230,0 -13231,0 -13232,0 -13233,0 -13234,0 -13235,0 -13236,0 -13237,0 -13238,0 -13239,0 -13240,0 -13241,0 -13242,0 -13243,0 -13244,0 -13245,0 -13246,0 -13247,0 -13248,0 -13249,0 -13250,0 -13251,0 -13252,0 -13253,0 -13254,0 -13255,0 -13256,0 -13257,0 -13258,0 -13259,0 -13260,0 -13261,0 -13262,0 -13263,0 -13264,0 -13265,0 -13266,0 -13267,0 -13268,0 -13269,0 -13270,0 -13271,0 -13272,0 -13273,0 -13274,0 -13275,0 -13276,0 -13277,0 -13278,0 -13279,0 -13280,0 -13281,0 -13282,0 -13283,0 -13284,0 -13285,0 -13286,0 -13287,0 -13288,0 -13289,0 -13290,0 -13291,0 -13292,0 -13293,0 -13294,0 -13295,0 -13296,0 -13297,0 -13298,0 -13299,0 -13300,0 -13301,0 -13302,0 -13303,0 -13304,0 -13305,0 -13306,0 -13307,0 -13308,0 -13309,0 -13310,0 -13311,0 -13312,0 -13313,0 -13314,0 -13315,0 -13316,0 -13317,0 -13318,0 -13319,0 -13320,0 -13321,0 -13322,0 -13323,0 -13324,0 -13325,0 -13326,0 -13327,0 -13328,0 -13329,0 -13330,0 -13331,0 -13332,0 -13333,0 -13334,0 -13335,0 -13336,0 -13337,0 -13338,0 -13339,0 -13340,0 -13341,0 -13342,0 -13343,0 -13344,0 -13345,0 -13346,0 -13347,0 -13348,0 -13349,0 -13350,0 -13351,0 -13352,0 -13353,0 -13354,0 -13355,0 -13356,0 -13357,0 -13358,0 -13359,0 -13360,0 -13361,0 -13362,0 -13363,0 -13364,0 -13365,0 -13366,0 -13367,0 -13368,0 -13369,0 -13370,0 -13371,0 -13372,0 -13373,0 -13374,0 -13375,0 -13376,0 -13377,0 -13378,0 -13379,0 -13380,0 -13381,0 -13382,0 -13383,0 -13384,0 -13385,0 -13386,0 -13387,0 -13388,0 -13389,0 -13390,0 -13391,0 -13392,0 -13393,0 -13394,0 -13395,0 -13396,0 -13397,0 -13398,0 -13399,0 -13400,0 -13401,0 -13402,0 -13403,0 -13404,0 -13405,0 -13406,0 -13407,0 -13408,0 -13409,0 -13410,0 -13411,0 -13412,0 -13413,0 -13414,0 -13415,0 -13416,0 -13417,0 -13418,0 -13419,0 -13420,0 -13421,0 -13422,0 -13423,0 -13424,0 -13425,0 -13426,0 -13427,0 -13428,0 -13429,0 -13430,0 -13431,0 -13432,0 -13433,0 -13434,0 -13435,0 -13436,0 -13437,0 -13438,0 -13439,0 -13440,0 -13441,0 -13442,0 -13443,0 -13444,0 -13445,0 -13446,0 -13447,0 -13448,0 -13449,0 -13450,0 -13451,0 -13452,0 -13453,0 -13454,0 -13455,0 -13456,0 -13457,0 -13458,0 -13459,0 -13460,0 -13461,0 -13462,0 -13463,0 -13464,0 -13465,0 -13466,0 -13467,0 -13468,0 -13469,0 -13470,0 -13471,0 -13472,0 -13473,0 -13474,0 -13475,0 -13476,0 -13477,0 -13478,0 -13479,0 -13480,0 -13481,0 -13482,0 -13483,0 -13484,0 -13485,0 -13486,0 -13487,0 -13488,0 -13489,0 -13490,0 -13491,0 -13492,0 -13493,0 -13494,0 -13495,0 -13496,0 -13497,0 -13498,0 -13499,0 -13500,0 -13501,0 -13502,0 -13503,0 -13504,0 -13505,0 -13506,0 -13507,0 -13508,0 -13509,0 -13510,0 -13511,0 -13512,0 -13513,0 -13514,0 -13515,0 -13516,0 -13517,0 -13518,0 -13519,0 -13520,0 -13521,0 -13522,0 -13523,0 -13524,0 -13525,0 -13526,0 -13527,0 -13528,0 -13529,0 -13530,0 -13531,0 -13532,0 -13533,0 -13534,0 -13535,0 -13536,0 -13537,0 -13538,0 -13539,0 -13540,0 -13541,0 -13542,0 -13543,0 -13544,0 -13545,0 -13546,0 -13547,0 -13548,0 -13549,0 -13550,0 -13551,0 -13552,0 -13553,0 -13554,0 -13555,0 -13556,0 -13557,0 -13558,0 -13559,0 -13560,0 -13561,0 -13562,0 -13563,0 -13564,0 -13565,0 -13566,0 -13567,0 -13568,0 -13569,0 -13570,0 -13571,0 -13572,0 -13573,0 -13574,0 -13575,0 -13576,0 -13577,0 -13578,0 -13579,0 -13580,0 -13581,0 -13582,0 -13583,0 -13584,0 -13585,0 -13586,0 -13587,0 -13588,0 -13589,0 -13590,0 -13591,0 -13592,0 -13593,0 -13594,0 -13595,0 -13596,0 -13597,0 -13598,0 -13599,0 -13600,0 -13601,0 -13602,0 -13603,0 -13604,0 -13605,0 -13606,0 -13607,0 -13608,0 -13609,0 -13610,0 -13611,0 -13612,0 -13613,0 -13614,0 -13615,0 -13616,0 -13617,0 -13618,0 -13619,0 -13620,0 -13621,0 -13622,0 -13623,0 -13624,0 -13625,0 -13626,0 -13627,0 -13628,0 -13629,0 -13630,0 -13631,0 -13632,0 -13633,0 -13634,0 -13635,0 -13636,0 -13637,0 -13638,0 -13639,0 -13640,0 -13641,0 -13642,0 -13643,0 -13644,0 -13645,0 -13646,0 -13647,0 -13648,0 -13649,0 -13650,0 -13651,0 -13652,0 -13653,0 -13654,0 -13655,0 -13656,0 -13657,0 -13658,0 -13659,0 -13660,0 -13661,0 -13662,0 -13663,0 -13664,0 -13665,0 -13666,0 -13667,0 -13668,0 -13669,0 -13670,0 -13671,0 -13672,0 -13673,0 -13674,0 -13675,0 -13676,0 -13677,0 -13678,0 -13679,0 -13680,0 -13681,0 -13682,0 -13683,0 -13684,0 -13685,0 -13686,0 -13687,0 -13688,0 -13689,0 -13690,0 -13691,0 -13692,0 -13693,0 -13694,0 -13695,0 -13696,0 -13697,0 -13698,0 -13699,0 -13700,0 -13701,0 -13702,0 -13703,0 -13704,0 -13705,0 -13706,0 -13707,0 -13708,0 -13709,0 -13710,0 -13711,0 -13712,0 -13713,0 -13714,0 -13715,0 -13716,0 -13717,0 -13718,0 -13719,0 -13720,0 -13721,0 -13722,0 -13723,0 -13724,0 -13725,0 -13726,0 -13727,0 -13728,0 -13729,0 -13730,0 -13731,0 -13732,0 -13733,0 -13734,0 -13735,0 -13736,0 -13737,0 -13738,0 -13739,0 -13740,0 -13741,0 -13742,0 -13743,0 -13744,0 -13745,0 -13746,0 -13747,0 -13748,0 -13749,0 -13750,0 -13751,0 -13752,0 -13753,0 -13754,0 -13755,0 -13756,0 -13757,0 -13758,0 -13759,0 -13760,0 -13761,0 -13762,0 -13763,0 -13764,0 -13765,0 -13766,0 -13767,0 -13768,0 -13769,0 -13770,0 -13771,0 -13772,0 -13773,0 -13774,0 -13775,0 -13776,0 -13777,0 -13778,0 -13779,0 -13780,0 -13781,0 -13782,0 -13783,0 -13784,0 -13785,0 -13786,0 -13787,0 -13788,0 -13789,0 -13790,0 -13791,0 -13792,0 -13793,0 -13794,0 -13795,0 -13796,0 -13797,0 -13798,0 -13799,0 -13800,0 -13801,0 -13802,0 -13803,0 -13804,0 -13805,0 -13806,0 -13807,0 -13808,0 -13809,0 -13810,0 -13811,0 -13812,0 -13813,0 -13814,0 -13815,0 -13816,0 -13817,0 -13818,0 -13819,0 -13820,0 -13821,0 -13822,0 -13823,0 -13824,0 -13825,0 -13826,0 -13827,0 -13828,0 -13829,0 -13830,0 -13831,0 -13832,0 -13833,0 -13834,0 -13835,0 -13836,0 -13837,0 -13838,0 -13839,0 -13840,0 -13841,0 -13842,0 -13843,0 -13844,0 -13845,0 -13846,0 -13847,0 -13848,0 -13849,0 -13850,0 -13851,0 -13852,0 -13853,0 -13854,0 -13855,0 -13856,0 -13857,0 -13858,0 -13859,0 -13860,0 -13861,0 -13862,0 -13863,0 -13864,0 -13865,0 -13866,0 -13867,0 -13868,0 -13869,0 -13870,0 -13871,0 -13872,0 -13873,0 -13874,0 -13875,0 -13876,0 -13877,0 -13878,0 -13879,0 -13880,0 -13881,0 -13882,0 -13883,0 -13884,0 -13885,0 -13886,0 -13887,0 -13888,0 -13889,0 -13890,0 -13891,0 -13892,0 -13893,0 -13894,0 -13895,0 -13896,0 -13897,0 -13898,0 -13899,0 -13900,0 -13901,0 -13902,0 -13903,0 -13904,0 -13905,0 -13906,0 -13907,0 -13908,0 -13909,0 -13910,0 -13911,0 -13912,0 -13913,0 -13914,0 -13915,0 -13916,0 -13917,0 -13918,0 -13919,0 -13920,0 -13921,0 -13922,0 -13923,0 -13924,0 -13925,0 -13926,0 -13927,0 -13928,0 -13929,0 -13930,0 -13931,0 -13932,0 -13933,0 -13934,0 -13935,0 -13936,0 -13937,0 -13938,0 -13939,0 -13940,0 -13941,0 -13942,0 -13943,0 -13944,0 -13945,0 -13946,0 -13947,0 -13948,0 -13949,0 -13950,0 -13951,0 -13952,0 -13953,0 -13954,0 -13955,0 -13956,0 -13957,0 -13958,0 -13959,0 -13960,0 -13961,0 -13962,0 -13963,0 -13964,0 -13965,0 -13966,0 -13967,0 -13968,0 -13969,0 -13970,0 -13971,0 -13972,0 -13973,0 -13974,0 -13975,0 -13976,0 -13977,0 -13978,0 -13979,0 -13980,0 -13981,0 -13982,0 -13983,0 -13984,0 -13985,0 -13986,0 -13987,0 -13988,0 -13989,0 -13990,0 -13991,0 -13992,0 -13993,0 -13994,0 -13995,0 -13996,0 -13997,0 -13998,0 -13999,0 -14000,0 -14001,0 -14002,0 -14003,0 -14004,0 -14005,0 -14006,0 -14007,0 -14008,0 -14009,0 -14010,0 -14011,0 -14012,0 -14013,0 -14014,0 -14015,0 -14016,0 -14017,0 -14018,0 -14019,0 -14020,0 -14021,0 -14022,0 -14023,0 -14024,0 -14025,0 -14026,0 -14027,0 -14028,0 -14029,0 -14030,0 -14031,0 -14032,0 -14033,0 -14034,0 -14035,0 -14036,0 -14037,0 -14038,0 -14039,0 -14040,0 -14041,0 -14042,0 -14043,0 -14044,0 -14045,0 -14046,0 -14047,0 -14048,0 -14049,0 -14050,0 -14051,0 -14052,0 -14053,0 -14054,0 -14055,0 -14056,0 -14057,0 -14058,0 -14059,0 -14060,0 -14061,0 -14062,0 -14063,0 -14064,0 -14065,0 -14066,0 -14067,0 -14068,0 -14069,0 -14070,0 -14071,0 -14072,0 -14073,0 -14074,0 -14075,0 -14076,0 -14077,0 -14078,0 -14079,0 -14080,0 -14081,0 -14082,0 -14083,0 -14084,0 -14085,0 -14086,0 -14087,0 -14088,0 -14089,0 -14090,0 -14091,0 -14092,0 -14093,0 -14094,0 -14095,0 -14096,0 -14097,0 -14098,0 -14099,0 -14100,0 -14101,0 -14102,0 -14103,0 -14104,0 -14105,0 -14106,0 -14107,0 -14108,0 -14109,0 -14110,0 -14111,0 -14112,0 -14113,0 -14114,0 -14115,0 -14116,0 -14117,0 -14118,0 -14119,0 -14120,0 -14121,0 -14122,0 -14123,0 -14124,0 -14125,0 -14126,0 -14127,0 -14128,0 -14129,0 -14130,0 -14131,0 -14132,0 -14133,0 -14134,0 -14135,0 -14136,0 -14137,0 -14138,0 -14139,0 -14140,0 -14141,0 -14142,0 -14143,0 -14144,0 -14145,0 -14146,0 -14147,0 -14148,0 -14149,0 -14150,0 -14151,0 -14152,0 -14153,0 -14154,0 -14155,0 -14156,0 -14157,0 -14158,0 -14159,0 -14160,0 -14161,0 -14162,0 -14163,0 -14164,0 -14165,0 -14166,0 -14167,0 -14168,0 -14169,0 -14170,0 -14171,0 -14172,0 -14173,0 -14174,0 -14175,0 -14176,0 -14177,0 -14178,0 -14179,0 -14180,0 -14181,0 -14182,0 -14183,0 -14184,0 -14185,0 -14186,0 -14187,0 -14188,0 -14189,0 -14190,0 -14191,0 -14192,0 -14193,0 -14194,0 -14195,0 -14196,0 -14197,0 -14198,0 -14199,0 -14200,0 -14201,0 -14202,0 -14203,0 -14204,0 -14205,0 -14206,0 -14207,0 -14208,0 -14209,0 -14210,0 -14211,0 -14212,0 -14213,0 -14214,0 -14215,0 -14216,0 -14217,0 -14218,0 -14219,0 -14220,0 -14221,0 -14222,0 -14223,0 -14224,0 -14225,0 -14226,0 -14227,0 -14228,0 -14229,0 -14230,0 -14231,0 -14232,0 -14233,0 -14234,0 -14235,0 -14236,0 -14237,0 -14238,0 -14239,0 -14240,0 -14241,0 -14242,0 -14243,0 -14244,0 -14245,0 -14246,0 -14247,0 -14248,0 -14249,0 -14250,0 -14251,0 -14252,0 -14253,0 -14254,0 -14255,0 -14256,0 -14257,0 -14258,0 -14259,0 -14260,0 -14261,0 -14262,0 -14263,0 -14264,0 -14265,0 -14266,0 -14267,0 -14268,0 -14269,0 -14270,0 -14271,0 -14272,0 -14273,0 -14274,0 -14275,0 -14276,0 -14277,0 -14278,0 -14279,0 -14280,0 -14281,0 -14282,0 -14283,0 -14284,0 -14285,0 -14286,0 -14287,0 -14288,0 -14289,0 -14290,0 -14291,0 -14292,0 -14293,0 -14294,0 -14295,0 -14296,0 -14297,0 -14298,0 -14299,0 -14300,0 -14301,0 -14302,0 -14303,0 -14304,0 -14305,0 -14306,0 -14307,0 -14308,0 -14309,0 -14310,0 -14311,0 -14312,0 -14313,0 -14314,0 -14315,0 -14316,0 -14317,0 -14318,0 -14319,0 -14320,0 -14321,0 -14322,0 -14323,0 -14324,0 -14325,0 -14326,0 -14327,0 -14328,0 -14329,0 -14330,0 -14331,0 -14332,0 -14333,0 -14334,0 -14335,0 -14336,0 -14337,0 -14338,0 -14339,0 -14340,0 -14341,0 -14342,0 -14343,0 -14344,0 -14345,0 -14346,0 -14347,0 -14348,0 -14349,0 -14350,0 -14351,0 -14352,0 -14353,0 -14354,0 -14355,0 -14356,0 -14357,0 -14358,0 -14359,0 -14360,0 -14361,0 -14362,0 -14363,0 -14364,0 -14365,0 -14366,0 -14367,0 -14368,0 -14369,0 -14370,0 -14371,0 -14372,0 -14373,0 -14374,0 -14375,0 -14376,0 -14377,0 -14378,0 -14379,0 -14380,0 -14381,0 -14382,0 -14383,0 -14384,0 -14385,0 -14386,0 -14387,0 -14388,0 -14389,0 -14390,0 -14391,0 -14392,0 -14393,0 -14394,0 -14395,0 -14396,0 -14397,0 -14398,0 -14399,0 -14400,0 -14401,0 -14402,0 -14403,0 -14404,0 -14405,0 -14406,0 -14407,0 -14408,0 -14409,0 -14410,0 -14411,0 -14412,0 -14413,0 -14414,0 -14415,0 -14416,0 -14417,0 -14418,0 -14419,0 -14420,0 -14421,0 -14422,0 -14423,0 -14424,0 -14425,0 -14426,0 -14427,0 -14428,0 -14429,0 -14430,0 -14431,0 -14432,0 -14433,0 -14434,0 -14435,0 -14436,0 -14437,0 -14438,0 -14439,0 -14440,0 -14441,0 -14442,0 -14443,0 -14444,0 -14445,0 -14446,0 -14447,0 -14448,0 -14449,0 -14450,0 -14451,0 -14452,0 -14453,0 -14454,0 -14455,0 -14456,0 -14457,0 -14458,0 -14459,0 -14460,0 -14461,0 -14462,0 -14463,0 -14464,0 -14465,0 -14466,0 -14467,0 -14468,0 -14469,0 -14470,0 -14471,0 -14472,0 -14473,0 -14474,0 -14475,0 -14476,0 -14477,0 -14478,0 -14479,0 -14480,0 -14481,0 -14482,0 -14483,0 -14484,0 -14485,0 -14486,0 -14487,0 -14488,0 -14489,0 -14490,0 -14491,0 -14492,0 -14493,0 -14494,0 -14495,0 -14496,0 -14497,0 -14498,0 -14499,0 -14500,0 -14501,0 -14502,0 -14503,0 -14504,0 -14505,0 -14506,0 -14507,0 -14508,0 -14509,0 -14510,0 -14511,0 -14512,0 -14513,0 -14514,0 -14515,0 -14516,0 -14517,0 -14518,0 -14519,0 -14520,0 -14521,0 -14522,0 -14523,0 -14524,0 -14525,0 -14526,0 -14527,0 -14528,0 -14529,0 -14530,0 -14531,0 -14532,0 -14533,0 -14534,0 -14535,0 -14536,0 -14537,0 -14538,0 -14539,0 -14540,0 -14541,0 -14542,0 -14543,0 -14544,0 -14545,0 -14546,0 -14547,0 -14548,0 -14549,0 -14550,0 -14551,0 -14552,0 -14553,0 -14554,0 -14555,0 -14556,0 -14557,0 -14558,0 -14559,0 -14560,0 -14561,0 -14562,0 -14563,0 -14564,0 -14565,0 -14566,0 -14567,0 -14568,0 -14569,0 -14570,0 -14571,0 -14572,0 -14573,0 -14574,0 -14575,0 -14576,0 -14577,0 -14578,0 -14579,0 -14580,0 -14581,0 -14582,0 -14583,0 -14584,0 -14585,0 -14586,0 -14587,0 -14588,0 -14589,0 -14590,0 -14591,0 -14592,0 -14593,0 -14594,0 -14595,0 -14596,0 -14597,0 -14598,0 -14599,0 -14600,0 -14601,0 -14602,0 -14603,0 -14604,0 -14605,0 -14606,0 -14607,0 -14608,0 -14609,0 -14610,0 -14611,0 -14612,0 -14613,0 -14614,0 -14615,0 -14616,0 -14617,0 -14618,0 -14619,0 -14620,0 -14621,0 -14622,0 -14623,0 -14624,0 -14625,0 -14626,0 -14627,0 -14628,0 -14629,0 -14630,0 -14631,0 -14632,0 -14633,0 -14634,0 -14635,0 -14636,0 -14637,0 -14638,0 -14639,0 -14640,0 -14641,0 -14642,0 -14643,0 -14644,0 -14645,0 -14646,0 -14647,0 -14648,0 -14649,0 -14650,0 -14651,0 -14652,0 -14653,0 -14654,0 -14655,0 -14656,0 -14657,0 -14658,0 -14659,0 -14660,0 -14661,0 -14662,0 -14663,0 -14664,0 -14665,0 -14666,0 -14667,0 -14668,0 -14669,0 -14670,0 -14671,0 -14672,0 -14673,0 -14674,0 -14675,0 -14676,0 -14677,0 -14678,0 -14679,0 -14680,0 -14681,0 -14682,0 -14683,0 -14684,0 -14685,0 -14686,0 -14687,0 -14688,0 -14689,0 -14690,0 -14691,0 -14692,0 -14693,0 -14694,0 -14695,0 -14696,0 -14697,0 -14698,0 -14699,0 -14700,0 -14701,0 -14702,0 -14703,0 -14704,0 -14705,0 -14706,0 -14707,0 -14708,0 -14709,0 -14710,0 -14711,0 -14712,0 -14713,0 -14714,0 -14715,0 -14716,0 -14717,0 -14718,0 -14719,0 -14720,0 -14721,0 -14722,0 -14723,0 -14724,0 -14725,0 -14726,0 -14727,0 -14728,0 -14729,0 -14730,0 -14731,0 -14732,0 -14733,0 -14734,0 -14735,0 -14736,0 -14737,0 -14738,0 -14739,0 -14740,0 -14741,0 -14742,0 -14743,0 -14744,0 -14745,0 -14746,0 -14747,0 -14748,0 -14749,0 -14750,0 -14751,0 -14752,0 -14753,0 -14754,0 -14755,0 -14756,0 -14757,0 -14758,0 -14759,0 -14760,0 -14761,0 -14762,0 -14763,0 -14764,0 -14765,0 -14766,0 -14767,0 -14768,0 -14769,0 -14770,0 -14771,0 -14772,0 -14773,0 -14774,0 -14775,0 -14776,0 -14777,0 -14778,0 -14779,0 -14780,0 -14781,0 -14782,0 -14783,0 -14784,0 -14785,0 -14786,0 -14787,0 -14788,0 -14789,0 -14790,0 -14791,0 -14792,0 -14793,0 -14794,0 -14795,0 -14796,0 -14797,0 -14798,0 -14799,0 -14800,0 -14801,0 -14802,0 -14803,0 -14804,0 -14805,0 -14806,0 -14807,0 -14808,0 -14809,0 -14810,0 -14811,0 -14812,0 -14813,0 -14814,0 -14815,0 -14816,0 -14817,0 -14818,0 -14819,0 -14820,0 -14821,0 -14822,0 -14823,0 -14824,0 -14825,0 -14826,0 -14827,0 -14828,0 -14829,0 -14830,0 -14831,0 -14832,0 -14833,0 -14834,0 -14835,0 -14836,0 -14837,0 -14838,0 -14839,0 -14840,0 -14841,0 -14842,0 -14843,0 -14844,0 -14845,0 -14846,0 -14847,0 -14848,0 -14849,0 -14850,0 -14851,0 -14852,0 -14853,0 -14854,0 -14855,0 -14856,0 -14857,0 -14858,0 -14859,0 -14860,0 -14861,0 -14862,0 -14863,0 -14864,0 -14865,0 -14866,0 -14867,0 -14868,0 -14869,0 -14870,0 -14871,0 -14872,0 -14873,0 -14874,0 -14875,0 -14876,0 -14877,0 -14878,0 -14879,0 -14880,0 -14881,0 -14882,0 -14883,0 -14884,0 -14885,0 -14886,0 -14887,0 -14888,0 -14889,0 -14890,0 -14891,0 -14892,0 -14893,0 -14894,0 -14895,0 -14896,0 -14897,0 -14898,0 -14899,0 -14900,0 -14901,0 -14902,0 -14903,0 -14904,0 -14905,0 -14906,0 -14907,0 -14908,0 -14909,0 -14910,0 -14911,0 -14912,0 -14913,0 -14914,0 -14915,0 -14916,0 -14917,0 -14918,0 -14919,0 -14920,0 -14921,0 -14922,0 -14923,0 -14924,0 -14925,0 -14926,0 -14927,0 -14928,0 -14929,0 -14930,0 -14931,0 -14932,0 -14933,0 -14934,0 -14935,0 -14936,0 -14937,0 -14938,0 -14939,0 -14940,0 -14941,0 -14942,0 -14943,0 -14944,0 -14945,0 -14946,0 -14947,0 -14948,0 -14949,0 -14950,0 -14951,0 -14952,0 -14953,0 -14954,0 -14955,0 -14956,0 -14957,0 -14958,0 -14959,0 -14960,0 -14961,0 -14962,0 -14963,0 -14964,0 -14965,0 -14966,0 -14967,0 -14968,0 -14969,0 -14970,0 -14971,0 -14972,0 -14973,0 -14974,0 -14975,0 -14976,0 -14977,0 -14978,0 -14979,0 -14980,0 -14981,0 -14982,0 -14983,0 -14984,0 -14985,0 -14986,0 -14987,0 -14988,0 -14989,0 -14990,0 -14991,0 -14992,0 -14993,0 -14994,0 -14995,0 -14996,0 -14997,0 -14998,0 -14999,0 -15000,0 -15001,0 -15002,0 -15003,0 -15004,0 -15005,0 -15006,0 -15007,0 -15008,0 -15009,0 -15010,0 -15011,0 -15012,0 -15013,0 -15014,0 -15015,0 -15016,0 -15017,0 -15018,0 -15019,0 -15020,0 -15021,0 -15022,0 -15023,0 -15024,0 -15025,0 -15026,0 -15027,0 -15028,0 -15029,0 -15030,0 -15031,0 -15032,0 -15033,0 -15034,0 -15035,0 -15036,0 -15037,0 -15038,0 -15039,0 -15040,0 -15041,0 -15042,0 -15043,0 -15044,0 -15045,0 -15046,0 -15047,0 -15048,0 -15049,0 -15050,0 -15051,0 -15052,0 -15053,0 -15054,0 -15055,0 -15056,0 -15057,0 -15058,0 -15059,0 -15060,0 -15061,0 -15062,0 -15063,0 -15064,0 -15065,0 -15066,0 -15067,0 -15068,0 -15069,0 -15070,0 -15071,0 -15072,0 -15073,0 -15074,0 -15075,0 -15076,0 -15077,0 -15078,0 -15079,0 -15080,0 -15081,0 -15082,0 -15083,0 -15084,0 -15085,0 -15086,0 -15087,0 -15088,0 -15089,0 -15090,0 -15091,0 -15092,0 -15093,0 -15094,0 -15095,0 -15096,0 -15097,0 -15098,0 -15099,0 -15100,0 -15101,0 -15102,0 -15103,0 -15104,0 -15105,0 -15106,0 -15107,0 -15108,0 -15109,0 -15110,0 -15111,0 -15112,0 -15113,0 -15114,0 -15115,0 -15116,0 -15117,0 -15118,0 -15119,0 -15120,0 -15121,0 -15122,0 -15123,0 -15124,0 -15125,0 -15126,0 -15127,0 -15128,0 -15129,0 -15130,0 -15131,0 -15132,0 -15133,0 -15134,0 -15135,0 -15136,0 -15137,0 -15138,0 -15139,0 -15140,0 -15141,0 -15142,0 -15143,0 -15144,0 -15145,0 -15146,0 -15147,0 -15148,0 -15149,0 -15150,0 -15151,0 -15152,0 -15153,0 -15154,0 -15155,0 -15156,0 -15157,0 -15158,0 -15159,0 -15160,0 -15161,0 -15162,0 -15163,0 -15164,0 -15165,0 -15166,0 -15167,0 -15168,0 -15169,0 -15170,0 -15171,0 -15172,0 -15173,0 -15174,0 -15175,0 -15176,0 -15177,0 -15178,0 -15179,0 -15180,0 -15181,0 -15182,0 -15183,0 -15184,0 -15185,0 -15186,0 -15187,0 -15188,0 -15189,0 -15190,0 -15191,0 -15192,0 -15193,0 -15194,0 -15195,0 -15196,0 -15197,0 -15198,0 -15199,0 -15200,0 -15201,0 -15202,0 -15203,0 -15204,0 -15205,0 -15206,0 -15207,0 -15208,0 -15209,0 -15210,0 -15211,0 -15212,0 -15213,0 -15214,0 -15215,0 -15216,0 -15217,0 -15218,0 -15219,0 -15220,0 -15221,0 -15222,0 -15223,0 -15224,0 -15225,0 -15226,0 -15227,0 -15228,0 -15229,0 -15230,0 -15231,0 -15232,0 -15233,0 -15234,0 -15235,0 -15236,0 -15237,0 -15238,0 -15239,0 -15240,0 -15241,0 -15242,0 -15243,0 -15244,0 -15245,0 -15246,0 -15247,0 -15248,0 -15249,0 -15250,0 -15251,0 -15252,0 -15253,0 -15254,0 -15255,0 -15256,0 -15257,0 -15258,0 -15259,0 -15260,0 -15261,0 -15262,0 -15263,0 -15264,0 -15265,0 -15266,0 -15267,0 -15268,0 -15269,0 -15270,0 -15271,0 -15272,0 -15273,0 -15274,0 -15275,0 -15276,0 -15277,0 -15278,0 -15279,0 -15280,0 -15281,0 -15282,0 -15283,0 -15284,0 -15285,0 -15286,0 -15287,0 -15288,0 -15289,0 -15290,0 -15291,0 -15292,0 -15293,0 -15294,0 -15295,0 -15296,0 -15297,0 -15298,0 -15299,0 -15300,0 -15301,0 -15302,0 -15303,0 -15304,0 -15305,0 -15306,0 -15307,0 -15308,0 -15309,0 -15310,0 -15311,0 -15312,0 -15313,0 -15314,0 -15315,0 -15316,0 -15317,0 -15318,0 -15319,0 -15320,0 -15321,0 -15322,0 -15323,0 -15324,0 -15325,0 -15326,0 -15327,0 -15328,0 -15329,0 -15330,0 -15331,0 -15332,0 -15333,0 -15334,0 -15335,0 -15336,0 -15337,0 -15338,0 -15339,0 -15340,0 -15341,0 -15342,0 -15343,0 -15344,0 -15345,0 -15346,0 -15347,0 -15348,0 -15349,0 -15350,0 -15351,0 -15352,0 -15353,0 -15354,0 -15355,0 -15356,0 -15357,0 -15358,0 -15359,0 -15360,0 -15361,0 -15362,0 -15363,0 -15364,0 -15365,0 -15366,0 -15367,0 -15368,0 -15369,0 -15370,0 -15371,0 -15372,0 -15373,0 -15374,0 -15375,0 -15376,0 -15377,0 -15378,0 -15379,0 -15380,0 -15381,0 -15382,0 -15383,0 -15384,0 -15385,0 -15386,0 -15387,0 -15388,0 -15389,0 -15390,0 -15391,0 -15392,0 -15393,0 -15394,0 -15395,0 -15396,0 -15397,0 -15398,0 -15399,0 -15400,0 -15401,0 -15402,0 -15403,0 -15404,0 -15405,0 -15406,0 -15407,0 -15408,0 -15409,0 -15410,0 -15411,0 -15412,0 -15413,0 -15414,0 -15415,0 -15416,0 -15417,0 -15418,0 -15419,0 -15420,0 -15421,0 -15422,0 -15423,0 -15424,0 -15425,0 -15426,0 -15427,0 -15428,0 -15429,0 -15430,0 -15431,0 -15432,0 -15433,0 -15434,0 -15435,0 -15436,0 -15437,0 -15438,0 -15439,0 -15440,0 -15441,0 -15442,0 -15443,0 -15444,0 -15445,0 -15446,0 -15447,0 -15448,0 -15449,0 -15450,0 -15451,0 -15452,0 -15453,0 -15454,0 -15455,0 -15456,0 -15457,0 -15458,0 -15459,0 -15460,0 -15461,0 -15462,0 -15463,0 -15464,0 -15465,0 -15466,0 -15467,0 -15468,0 -15469,0 -15470,0 -15471,0 -15472,0 -15473,0 -15474,0 -15475,0 -15476,0 -15477,0 -15478,0 -15479,0 -15480,0 -15481,0 -15482,0 -15483,0 -15484,0 -15485,0 -15486,0 -15487,0 -15488,0 -15489,0 -15490,0 -15491,0 -15492,0 -15493,0 -15494,0 -15495,0 -15496,0 -15497,0 -15498,0 -15499,0 -15500,0 -15501,0 -15502,0 -15503,0 -15504,0 -15505,0 -15506,0 -15507,0 -15508,0 -15509,0 -15510,0 -15511,0 -15512,0 -15513,0 -15514,0 -15515,0 -15516,0 -15517,0 -15518,0 -15519,0 -15520,0 -15521,0 -15522,0 -15523,0 -15524,0 -15525,0 -15526,0 -15527,0 -15528,0 -15529,0 -15530,0 -15531,0 -15532,0 -15533,0 -15534,0 -15535,0 -15536,0 -15537,0 -15538,0 -15539,0 -15540,0 -15541,0 -15542,0 -15543,0 -15544,0 -15545,0 -15546,0 -15547,0 -15548,0 -15549,0 -15550,0 -15551,0 -15552,0 -15553,0 -15554,0 -15555,0 -15556,0 -15557,0 -15558,0 -15559,0 -15560,0 -15561,0 -15562,0 -15563,0 -15564,0 -15565,0 -15566,0 -15567,0 -15568,0 -15569,0 -15570,0 -15571,0 -15572,0 -15573,0 -15574,0 -15575,0 -15576,0 -15577,0 -15578,0 -15579,0 -15580,0 -15581,0 -15582,0 -15583,0 -15584,0 -15585,0 -15586,0 -15587,0 -15588,0 -15589,0 -15590,0 -15591,0 -15592,0 -15593,0 -15594,0 -15595,0 -15596,0 -15597,0 -15598,0 -15599,0 -15600,0 -15601,0 -15602,0 -15603,0 -15604,0 -15605,0 -15606,0 -15607,0 -15608,0 -15609,0 -15610,0 -15611,0 -15612,0 -15613,0 -15614,0 -15615,0 -15616,0 -15617,0 -15618,0 -15619,0 -15620,0 -15621,0 -15622,0 -15623,0 -15624,0 -15625,0 -15626,0 -15627,0 -15628,0 -15629,0 -15630,0 -15631,0 -15632,0 -15633,0 -15634,0 -15635,0 -15636,0 -15637,0 -15638,0 -15639,0 -15640,0 -15641,0 -15642,0 -15643,0 -15644,0 -15645,0 -15646,0 -15647,0 -15648,0 -15649,0 -15650,0 -15651,0 -15652,0 -15653,0 -15654,0 -15655,0 -15656,0 -15657,0 -15658,0 -15659,0 -15660,0 -15661,0 -15662,0 -15663,0 -15664,0 -15665,0 -15666,0 -15667,0 -15668,0 -15669,0 -15670,0 -15671,0 -15672,0 -15673,0 -15674,0 -15675,0 -15676,0 -15677,0 -15678,0 -15679,0 -15680,0 -15681,0 -15682,0 -15683,0 -15684,0 -15685,0 -15686,0 -15687,0 -15688,0 -15689,0 -15690,0 -15691,0 -15692,0 -15693,0 -15694,0 -15695,0 -15696,0 -15697,0 -15698,0 -15699,0 -15700,0 -15701,0 -15702,0 -15703,0 -15704,0 -15705,0 -15706,0 -15707,0 -15708,0 -15709,0 -15710,0 -15711,0 -15712,0 -15713,0 -15714,0 -15715,0 -15716,0 -15717,0 -15718,0 -15719,0 -15720,0 -15721,0 -15722,0 -15723,0 -15724,0 -15725,0 -15726,0 -15727,0 -15728,0 -15729,0 -15730,0 -15731,0 -15732,0 -15733,0 -15734,0 -15735,0 -15736,0 -15737,0 -15738,0 -15739,0 -15740,0 -15741,0 -15742,0 -15743,0 -15744,0 -15745,0 -15746,0 -15747,0 -15748,0 -15749,0 -15750,0 -15751,0 -15752,0 -15753,0 -15754,0 -15755,0 -15756,0 -15757,0 -15758,0 -15759,0 -15760,0 -15761,0 -15762,0 -15763,0 -15764,0 -15765,0 -15766,0 -15767,0 -15768,0 -15769,0 -15770,0 -15771,0 -15772,0 -15773,0 -15774,0 -15775,0 -15776,0 -15777,0 -15778,0 -15779,0 -15780,0 -15781,0 -15782,0 -15783,0 -15784,0 -15785,0 -15786,0 -15787,0 -15788,0 -15789,0 -15790,0 -15791,0 -15792,0 -15793,0 -15794,0 -15795,0 -15796,0 -15797,0 -15798,0 -15799,0 -15800,0 -15801,0 -15802,0 -15803,0 -15804,0 -15805,0 -15806,0 -15807,0 -15808,0 -15809,0 -15810,0 -15811,0 -15812,0 -15813,0 -15814,0 -15815,0 -15816,0 -15817,0 -15818,0 -15819,0 -15820,0 -15821,0 -15822,0 -15823,0 -15824,0 -15825,0 -15826,0 -15827,0 -15828,0 -15829,0 -15830,0 -15831,0 -15832,0 -15833,0 -15834,0 -15835,0 -15836,0 -15837,0 -15838,0 -15839,0 -15840,0 -15841,0 -15842,0 -15843,0 -15844,0 -15845,0 -15846,0 -15847,0 -15848,0 -15849,0 -15850,0 -15851,0 -15852,0 -15853,0 -15854,0 -15855,0 -15856,0 -15857,0 -15858,0 -15859,0 -15860,0 -15861,0 -15862,0 -15863,0 -15864,0 -15865,0 -15866,0 -15867,0 -15868,0 -15869,0 -15870,0 -15871,0 -15872,0 -15873,0 -15874,0 -15875,0 -15876,0 -15877,0 -15878,0 -15879,0 -15880,0 -15881,0 -15882,0 -15883,0 -15884,0 -15885,0 -15886,0 -15887,0 -15888,0 -15889,0 -15890,0 -15891,0 -15892,0 -15893,0 -15894,0 -15895,0 -15896,0 -15897,0 -15898,0 -15899,0 -15900,0 -15901,0 -15902,0 -15903,0 -15904,0 -15905,0 -15906,0 -15907,0 -15908,0 -15909,0 -15910,0 -15911,0 -15912,0 -15913,0 -15914,0 -15915,0 -15916,0 -15917,0 -15918,0 -15919,0 -15920,0 -15921,0 -15922,0 -15923,0 -15924,0 -15925,0 -15926,0 -15927,0 -15928,0 -15929,0 -15930,0 -15931,0 -15932,0 -15933,0 -15934,0 -15935,0 -15936,0 -15937,0 -15938,0 -15939,0 -15940,0 -15941,0 -15942,0 -15943,0 -15944,0 -15945,0 -15946,0 -15947,0 -15948,0 -15949,0 -15950,0 -15951,0 -15952,0 -15953,0 -15954,0 -15955,0 -15956,0 -15957,0 -15958,0 -15959,0 -15960,0 -15961,0 -15962,0 -15963,0 -15964,0 -15965,0 -15966,0 -15967,0 -15968,0 -15969,0 -15970,0 -15971,0 -15972,0 -15973,0 -15974,0 -15975,0 -15976,0 -15977,0 -15978,0 -15979,0 -15980,0 -15981,0 -15982,0 -15983,0 -15984,0 -15985,0 -15986,0 -15987,0 -15988,0 -15989,0 -15990,0 -15991,0 -15992,0 -15993,0 -15994,0 -15995,0 -15996,0 -15997,0 -15998,0 -15999,0 -16000,0 -16001,0 -16002,0 -16003,0 -16004,0 -16005,0 -16006,0 -16007,0 -16008,0 -16009,0 -16010,0 -16011,0 -16012,0 -16013,0 -16014,0 -16015,0 -16016,0 -16017,0 -16018,0 -16019,0 -16020,0 -16021,0 -16022,0 -16023,0 -16024,0 -16025,0 -16026,0 -16027,0 -16028,0 -16029,0 -16030,0 -16031,0 -16032,0 -16033,0 -16034,0 -16035,0 -16036,0 -16037,0 -16038,0 -16039,0 -16040,0 -16041,0 -16042,0 -16043,0 -16044,0 -16045,0 -16046,0 -16047,0 -16048,0 -16049,0 -16050,0 -16051,0 -16052,0 -16053,0 -16054,0 -16055,0 -16056,0 -16057,0 -16058,0 -16059,0 -16060,0 -16061,0 -16062,0 -16063,0 -16064,0 -16065,0 -16066,0 -16067,0 -16068,0 -16069,0 -16070,0 -16071,0 -16072,0 -16073,0 -16074,0 -16075,0 -16076,0 -16077,0 -16078,0 -16079,0 -16080,0 -16081,0 -16082,0 -16083,0 -16084,0 -16085,0 -16086,0 -16087,0 -16088,0 -16089,0 -16090,0 -16091,0 -16092,0 -16093,0 -16094,0 -16095,0 -16096,0 -16097,0 -16098,0 -16099,0 -16100,0 -16101,0 -16102,0 -16103,0 -16104,0 -16105,0 -16106,0 -16107,0 -16108,0 -16109,0 -16110,0 -16111,0 -16112,0 -16113,0 -16114,0 -16115,0 -16116,0 -16117,0 -16118,0 -16119,0 -16120,0 -16121,0 -16122,0 -16123,0 -16124,0 -16125,0 -16126,0 -16127,0 -16128,0 -16129,0 -16130,0 -16131,0 -16132,0 -16133,0 -16134,0 -16135,0 -16136,0 -16137,0 -16138,0 -16139,0 -16140,0 -16141,0 -16142,0 -16143,0 -16144,0 -16145,0 -16146,0 -16147,0 -16148,0 -16149,0 -16150,0 -16151,0 -16152,0 -16153,0 -16154,0 -16155,0 -16156,0 -16157,0 -16158,0 -16159,0 -16160,0 -16161,0 -16162,0 -16163,0 -16164,0 -16165,0 -16166,0 -16167,0 -16168,0 -16169,0 -16170,0 -16171,0 -16172,0 -16173,0 -16174,0 -16175,0 -16176,0 -16177,0 -16178,0 -16179,0 -16180,0 -16181,0 -16182,0 -16183,0 -16184,0 -16185,0 -16186,0 -16187,0 -16188,0 -16189,0 -16190,0 -16191,0 -16192,0 -16193,0 -16194,0 -16195,0 -16196,0 -16197,0 -16198,0 -16199,0 -16200,0 -16201,0 -16202,0 -16203,0 -16204,0 -16205,0 -16206,0 -16207,0 -16208,0 -16209,0 -16210,0 -16211,0 -16212,0 -16213,0 -16214,0 -16215,0 -16216,0 -16217,0 -16218,0 -16219,0 -16220,0 -16221,0 -16222,0 -16223,0 -16224,0 -16225,0 -16226,0 -16227,0 -16228,0 -16229,0 -16230,0 -16231,0 -16232,0 -16233,0 -16234,0 -16235,0 -16236,0 -16237,0 -16238,0 -16239,0 -16240,0 -16241,0 -16242,0 -16243,0 -16244,0 -16245,0 -16246,0 -16247,0 -16248,0 -16249,0 -16250,0 -16251,0 -16252,0 -16253,0 -16254,0 -16255,0 -16256,0 -16257,0 -16258,0 -16259,0 -16260,0 -16261,0 -16262,0 -16263,0 -16264,0 -16265,0 -16266,0 -16267,0 -16268,0 -16269,0 -16270,0 -16271,0 -16272,0 -16273,0 -16274,0 -16275,0 -16276,0 -16277,0 -16278,0 -16279,0 -16280,0 -16281,0 -16282,0 -16283,0 -16284,0 -16285,0 -16286,0 -16287,0 -16288,0 -16289,0 -16290,0 -16291,0 -16292,0 -16293,0 -16294,0 -16295,0 -16296,0 -16297,0 -16298,0 -16299,0 -16300,0 -16301,0 -16302,0 -16303,0 -16304,0 -16305,0 -16306,0 -16307,0 -16308,0 -16309,0 -16310,0 -16311,0 -16312,0 -16313,0 -16314,0 -16315,0 -16316,0 -16317,0 -16318,0 -16319,0 -16320,0 -16321,0 -16322,0 -16323,0 -16324,0 -16325,0 -16326,0 -16327,0 -16328,0 -16329,0 -16330,0 -16331,0 -16332,0 -16333,0 -16334,0 -16335,0 -16336,0 -16337,0 -16338,0 -16339,0 -16340,0 -16341,0 -16342,0 -16343,0 -16344,0 -16345,0 -16346,0 -16347,0 -16348,0 -16349,0 -16350,0 -16351,0 -16352,0 -16353,0 -16354,0 -16355,0 -16356,0 -16357,0 -16358,0 -16359,0 -16360,0 -16361,0 -16362,0 -16363,0 -16364,0 -16365,0 -16366,0 -16367,0 -16368,0 -16369,0 -16370,0 -16371,0 -16372,0 -16373,0 -16374,0 -16375,0 -16376,0 -16377,0 -16378,0 -16379,0 -16380,0 -16381,0 -16382,0 -16383,0 -16384,0 -16385,0 -16386,0 -16387,0 -16388,0 -16389,0 -16390,0 -16391,0 -16392,0 -16393,0 -16394,0 -16395,0 -16396,0 -16397,0 -16398,0 -16399,0 -16400,0 -16401,0 -16402,0 -16403,0 -16404,0 -16405,0 -16406,0 -16407,0 -16408,0 -16409,0 -16410,0 -16411,0 -16412,0 -16413,0 -16414,0 -16415,0 -16416,0 -16417,0 -16418,0 -16419,0 -16420,0 -16421,0 -16422,0 -16423,0 -16424,0 -16425,0 -16426,0 -16427,0 -16428,0 -16429,0 -16430,0 -16431,0 -16432,0 -16433,0 -16434,0 -16435,0 -16436,0 -16437,0 -16438,0 -16439,0 -16440,0 -16441,0 -16442,0 -16443,0 -16444,0 -16445,0 -16446,0 -16447,0 -16448,0 -16449,0 -16450,0 -16451,0 -16452,0 -16453,0 -16454,0 -16455,0 -16456,0 -16457,0 -16458,0 -16459,0 -16460,0 -16461,0 -16462,0 -16463,0 -16464,0 -16465,0 -16466,0 -16467,0 -16468,0 -16469,0 -16470,0 -16471,0 -16472,0 -16473,0 -16474,0 -16475,0 -16476,0 -16477,0 -16478,0 -16479,0 -16480,0 -16481,0 -16482,0 -16483,0 -16484,0 -16485,0 -16486,0 -16487,0 -16488,0 -16489,0 -16490,0 -16491,0 -16492,0 -16493,0 -16494,0 -16495,0 -16496,0 -16497,0 -16498,0 -16499,0 -16500,0 -16501,0 -16502,0 -16503,0 -16504,0 -16505,0 -16506,0 -16507,0 -16508,0 -16509,0 -16510,0 -16511,0 -16512,0 -16513,0 -16514,0 -16515,0 -16516,0 -16517,0 -16518,0 -16519,0 -16520,0 -16521,0 -16522,0 -16523,0 -16524,0 -16525,0 -16526,0 -16527,0 -16528,0 -16529,0 -16530,0 -16531,0 -16532,0 -16533,0 -16534,0 -16535,0 -16536,0 -16537,0 -16538,0 -16539,0 -16540,0 -16541,0 -16542,0 -16543,0 -16544,0 -16545,0 -16546,0 -16547,0 -16548,0 -16549,0 -16550,0 -16551,0 -16552,0 -16553,0 -16554,0 -16555,0 -16556,0 -16557,0 -16558,0 -16559,0 -16560,0 -16561,0 -16562,0 -16563,0 -16564,0 -16565,0 -16566,0 -16567,0 -16568,0 -16569,0 -16570,0 -16571,0 -16572,0 -16573,0 -16574,0 -16575,0 -16576,0 -16577,0 -16578,0 -16579,0 -16580,0 -16581,0 -16582,0 -16583,0 -16584,0 -16585,0 -16586,0 -16587,0 -16588,0 -16589,0 -16590,0 -16591,0 -16592,0 -16593,0 -16594,0 -16595,0 -16596,0 -16597,0 -16598,0 -16599,0 -16600,0 -16601,0 -16602,0 -16603,0 -16604,0 -16605,0 -16606,0 -16607,0 -16608,0 -16609,0 -16610,0 -16611,0 -16612,0 -16613,0 -16614,0 -16615,0 -16616,0 -16617,0 -16618,0 -16619,0 -16620,0 -16621,0 -16622,0 -16623,0 -16624,0 -16625,0 -16626,0 -16627,0 -16628,0 -16629,0 -16630,0 -16631,0 -16632,0 -16633,0 -16634,0 -16635,0 -16636,0 -16637,0 -16638,0 -16639,0 -16640,0 -16641,0 -16642,0 -16643,0 -16644,0 -16645,0 -16646,0 -16647,0 -16648,0 -16649,0 -16650,0 -16651,0 -16652,0 -16653,0 -16654,0 -16655,0 -16656,0 -16657,0 -16658,0 -16659,0 -16660,0 -16661,0 -16662,0 -16663,0 -16664,0 -16665,0 -16666,0 -16667,0 -16668,0 -16669,0 -16670,0 -16671,0 -16672,0 -16673,0 -16674,0 -16675,0 -16676,0 -16677,0 -16678,0 -16679,0 -16680,0 -16681,0 -16682,0 -16683,0 -16684,0 -16685,0 -16686,0 -16687,0 -16688,0 -16689,0 -16690,0 -16691,0 -16692,0 -16693,0 -16694,0 -16695,0 -16696,0 -16697,0 -16698,0 -16699,0 -16700,0 -16701,0 -16702,0 -16703,0 -16704,0 -16705,0 -16706,0 -16707,0 -16708,0 -16709,0 -16710,0 -16711,0 -16712,0 -16713,0 -16714,0 -16715,0 -16716,0 -16717,0 -16718,0 -16719,0 -16720,0 -16721,0 -16722,0 -16723,0 -16724,0 -16725,0 -16726,0 -16727,0 -16728,0 -16729,0 -16730,0 -16731,0 -16732,0 -16733,0 -16734,0 -16735,0 -16736,0 -16737,0 -16738,0 -16739,0 -16740,0 -16741,0 -16742,0 -16743,0 -16744,0 -16745,0 -16746,0 -16747,0 -16748,0 -16749,0 -16750,0 -16751,0 -16752,0 -16753,0 -16754,0 -16755,0 -16756,0 -16757,0 -16758,0 -16759,0 -16760,0 -16761,0 -16762,0 -16763,0 -16764,0 -16765,0 -16766,0 -16767,0 -16768,0 -16769,0 -16770,0 -16771,0 -16772,0 -16773,0 -16774,0 -16775,0 -16776,0 -16777,0 -16778,0 -16779,0 -16780,0 -16781,0 -16782,0 -16783,0 -16784,0 -16785,0 -16786,0 -16787,0 -16788,0 -16789,0 -16790,0 -16791,0 -16792,0 -16793,0 -16794,0 -16795,0 -16796,0 -16797,0 -16798,0 -16799,0 -16800,0 -16801,0 -16802,0 -16803,0 -16804,0 -16805,0 -16806,0 -16807,0 -16808,0 -16809,0 -16810,0 -16811,0 -16812,0 -16813,0 -16814,0 -16815,0 -16816,0 -16817,0 -16818,0 -16819,0 -16820,0 -16821,0 -16822,0 -16823,0 -16824,0 -16825,0 -16826,0 -16827,0 -16828,0 -16829,0 -16830,0 -16831,0 -16832,0 -16833,0 -16834,0 -16835,0 -16836,0 -16837,0 -16838,0 -16839,0 -16840,0 -16841,0 -16842,0 -16843,0 -16844,0 -16845,0 -16846,0 -16847,0 -16848,0 -16849,0 -16850,0 -16851,0 -16852,0 -16853,0 -16854,0 -16855,0 -16856,0 -16857,0 -16858,0 -16859,0 -16860,0 -16861,0 -16862,0 -16863,0 -16864,0 -16865,0 -16866,0 -16867,0 -16868,0 -16869,0 -16870,0 -16871,0 -16872,0 -16873,0 -16874,0 -16875,0 -16876,0 -16877,0 -16878,0 -16879,0 -16880,0 -16881,0 -16882,0 -16883,0 -16884,0 -16885,0 -16886,0 -16887,0 -16888,0 -16889,0 -16890,0 -16891,0 -16892,0 -16893,0 -16894,0 -16895,0 -16896,0 -16897,0 -16898,0 -16899,0 -16900,0 -16901,0 -16902,0 -16903,0 -16904,0 -16905,0 -16906,0 -16907,0 -16908,0 -16909,0 -16910,0 -16911,0 -16912,0 -16913,0 -16914,0 -16915,0 -16916,0 -16917,0 -16918,0 -16919,0 -16920,0 -16921,0 -16922,0 -16923,0 -16924,0 -16925,0 -16926,0 -16927,0 -16928,0 -16929,0 -16930,0 -16931,0 -16932,0 -16933,0 -16934,0 -16935,0 -16936,0 -16937,0 -16938,0 -16939,0 -16940,0 -16941,0 -16942,0 -16943,0 -16944,0 -16945,0 -16946,0 -16947,0 -16948,0 -16949,0 -16950,0 -16951,0 -16952,0 -16953,0 -16954,0 -16955,0 -16956,0 -16957,0 -16958,0 -16959,0 -16960,0 -16961,0 -16962,0 -16963,0 -16964,0 -16965,0 -16966,0 -16967,0 -16968,0 -16969,0 -16970,0 -16971,0 -16972,0 -16973,0 -16974,0 -16975,0 -16976,0 -16977,0 -16978,0 -16979,0 -16980,0 -16981,0 -16982,0 -16983,0 -16984,0 -16985,0 -16986,0 -16987,0 -16988,0 -16989,0 -16990,0 -16991,0 -16992,0 -16993,0 -16994,0 -16995,0 -16996,0 -16997,0 -16998,0 -16999,0 -17000,0 -17001,0 -17002,0 -17003,0 -17004,0 -17005,0 -17006,0 -17007,0 -17008,0 -17009,0 -17010,0 -17011,0 -17012,0 -17013,0 -17014,0 -17015,0 -17016,0 -17017,0 -17018,0 -17019,0 -17020,0 -17021,0 -17022,0 -17023,0 -17024,0 -17025,0 -17026,0 -17027,0 -17028,0 -17029,0 -17030,0 -17031,0 -17032,0 -17033,0 -17034,0 -17035,0 -17036,0 -17037,0 -17038,0 -17039,0 -17040,0 -17041,0 -17042,0 -17043,0 -17044,0 -17045,0 -17046,0 -17047,0 -17048,0 -17049,0 -17050,0 -17051,0 -17052,0 -17053,0 -17054,0 -17055,0 -17056,0 -17057,0 -17058,0 -17059,0 -17060,0 -17061,0 -17062,0 -17063,0 -17064,0 -17065,0 -17066,0 -17067,0 -17068,0 -17069,0 -17070,0 -17071,0 -17072,0 -17073,0 -17074,0 -17075,0 -17076,0 -17077,0 -17078,0 -17079,0 -17080,0 -17081,0 -17082,0 -17083,0 -17084,0 -17085,0 -17086,0 -17087,0 -17088,0 -17089,0 -17090,0 -17091,0 -17092,0 -17093,0 -17094,0 -17095,0 -17096,0 -17097,0 -17098,0 -17099,0 -17100,0 -17101,0 -17102,0 -17103,0 -17104,0 -17105,0 -17106,0 -17107,0 -17108,0 -17109,0 -17110,0 -17111,0 -17112,0 -17113,0 -17114,0 -17115,0 -17116,0 -17117,0 -17118,0 -17119,0 -17120,0 -17121,0 -17122,0 -17123,0 -17124,0 -17125,0 -17126,0 -17127,0 -17128,0 -17129,0 -17130,0 -17131,0 -17132,0 -17133,0 -17134,0 -17135,0 -17136,0 -17137,0 -17138,0 -17139,0 -17140,0 -17141,0 -17142,0 -17143,0 -17144,0 -17145,0 -17146,0 -17147,0 -17148,0 -17149,0 -17150,0 -17151,0 -17152,0 -17153,0 -17154,0 -17155,0 -17156,0 -17157,0 -17158,0 -17159,0 -17160,0 -17161,0 -17162,0 -17163,0 -17164,0 -17165,0 -17166,0 -17167,0 -17168,0 -17169,0 -17170,0 -17171,0 -17172,0 -17173,0 -17174,0 -17175,0 -17176,0 -17177,0 -17178,0 -17179,0 -17180,0 -17181,0 -17182,0 -17183,0 -17184,0 -17185,0 -17186,0 -17187,0 -17188,0 -17189,0 -17190,0 -17191,0 -17192,0 -17193,0 -17194,0 -17195,0 -17196,0 -17197,0 -17198,0 -17199,0 -17200,0 -17201,0 -17202,0 -17203,0 -17204,0 -17205,0 -17206,0 -17207,0 -17208,0 -17209,0 -17210,0 -17211,0 -17212,0 -17213,0 -17214,0 -17215,0 -17216,0 -17217,0 -17218,0 -17219,0 -17220,0 -17221,0 -17222,0 -17223,0 -17224,0 -17225,0 -17226,0 -17227,0 -17228,0 -17229,0 -17230,0 -17231,0 -17232,0 -17233,0 -17234,0 -17235,0 -17236,0 -17237,0 -17238,0 -17239,0 -17240,0 -17241,0 -17242,0 -17243,0 -17244,0 -17245,0 -17246,0 -17247,0 -17248,0 -17249,0 -17250,0 -17251,0 -17252,0 -17253,0 -17254,0 -17255,0 -17256,0 -17257,0 -17258,0 -17259,0 -17260,0 -17261,0 -17262,0 -17263,0 -17264,0 -17265,0 -17266,0 -17267,0 -17268,0 -17269,0 -17270,0 -17271,0 -17272,0 -17273,0 -17274,0 -17275,0 -17276,0 -17277,0 -17278,0 -17279,0 -17280,0 -17281,0 -17282,0 -17283,0 -17284,0 -17285,0 -17286,0 -17287,0 -17288,0 -17289,0 -17290,0 -17291,0 -17292,0 -17293,0 -17294,0 -17295,0 -17296,0 -17297,0 -17298,0 -17299,0 -17300,0 -17301,0 -17302,0 -17303,0 -17304,0 -17305,0 -17306,0 -17307,0 -17308,0 -17309,0 -17310,0 -17311,0 -17312,0 -17313,0 -17314,0 -17315,0 -17316,0 -17317,0 -17318,0 -17319,0 -17320,0 -17321,0 -17322,0 -17323,0 -17324,0 -17325,0 -17326,0 -17327,0 -17328,0 -17329,0 -17330,0 -17331,0 -17332,0 -17333,0 -17334,0 -17335,0 -17336,0 -17337,0 -17338,0 -17339,0 -17340,0 -17341,0 -17342,0 -17343,0 -17344,0 -17345,0 -17346,0 -17347,0 -17348,0 -17349,0 -17350,0 -17351,0 -17352,0 -17353,0 -17354,0 -17355,0 -17356,0 -17357,0 -17358,0 -17359,0 -17360,0 -17361,0 -17362,0 -17363,0 -17364,0 -17365,0 -17366,0 -17367,0 -17368,0 -17369,0 -17370,0 -17371,0 -17372,0 -17373,0 -17374,0 -17375,0 -17376,0 -17377,0 -17378,0 -17379,0 -17380,0 -17381,0 -17382,0 -17383,0 -17384,0 -17385,0 -17386,0 -17387,0 -17388,0 -17389,0 -17390,0 -17391,0 -17392,0 -17393,0 -17394,0 -17395,0 -17396,0 -17397,0 -17398,0 -17399,0 -17400,0 -17401,0 -17402,0 -17403,0 -17404,0 -17405,0 -17406,0 -17407,0 -17408,0 -17409,0 -17410,0 -17411,0 -17412,0 -17413,0 -17414,0 -17415,0 -17416,0 -17417,0 -17418,0 -17419,0 -17420,0 -17421,0 -17422,0 -17423,0 -17424,0 -17425,0 -17426,0 -17427,0 -17428,0 -17429,0 -17430,0 -17431,0 -17432,0 -17433,0 -17434,0 -17435,0 -17436,0 -17437,0 -17438,0 -17439,0 -17440,0 -17441,0 -17442,0 -17443,0 -17444,0 -17445,0 -17446,0 -17447,0 -17448,0 -17449,0 -17450,0 -17451,0 -17452,0 -17453,0 -17454,0 -17455,0 -17456,0 -17457,0 -17458,0 -17459,0 -17460,0 -17461,0 -17462,0 -17463,0 -17464,0 -17465,0 -17466,0 -17467,0 -17468,0 -17469,0 -17470,0 -17471,0 -17472,0 -17473,0 -17474,0 -17475,0 -17476,0 -17477,0 -17478,0 -17479,0 -17480,0 -17481,0 -17482,0 -17483,0 -17484,0 -17485,0 -17486,0 -17487,0 -17488,0 -17489,0 -17490,0 -17491,0 -17492,0 -17493,0 -17494,0 -17495,0 -17496,0 -17497,0 -17498,0 -17499,0 -17500,0 -17501,0 -17502,0 -17503,0 -17504,0 -17505,0 -17506,0 -17507,0 -17508,0 -17509,0 -17510,0 -17511,0 -17512,0 -17513,0 -17514,0 -17515,0 -17516,0 -17517,0 -17518,0 -17519,0 -17520,0 -17521,0 -17522,0 -17523,0 -17524,0 -17525,0 -17526,0 -17527,0 -17528,0 -17529,0 -17530,0 -17531,0 -17532,0 -17533,0 -17534,0 -17535,0 -17536,0 -17537,0 -17538,0 -17539,0 -17540,0 -17541,0 -17542,0 -17543,0 -17544,0 -17545,0 -17546,0 -17547,0 -17548,0 -17549,0 -17550,0 -17551,0 -17552,0 -17553,0 -17554,0 -17555,0 -17556,0 -17557,0 -17558,0 -17559,0 -17560,0 -17561,0 -17562,0 -17563,0 -17564,0 -17565,0 -17566,0 -17567,0 -17568,0 -17569,0 -17570,0 -17571,0 -17572,0 -17573,0 -17574,0 -17575,0 -17576,0 -17577,0 -17578,0 -17579,0 -17580,0 -17581,0 -17582,0 -17583,0 -17584,0 -17585,0 -17586,0 -17587,0 -17588,0 -17589,0 -17590,0 -17591,0 -17592,0 -17593,0 -17594,0 -17595,0 -17596,0 -17597,0 -17598,0 -17599,0 -17600,0 -17601,0 -17602,0 -17603,0 -17604,0 -17605,0 -17606,0 -17607,0 -17608,0 -17609,0 -17610,0 -17611,0 -17612,0 -17613,0 -17614,0 -17615,0 -17616,0 -17617,0 -17618,0 -17619,0 -17620,0 -17621,0 -17622,0 -17623,0 -17624,0 -17625,0 -17626,0 -17627,0 -17628,0 -17629,0 -17630,0 -17631,0 -17632,0 -17633,0 -17634,0 -17635,0 -17636,0 -17637,0 -17638,0 -17639,0 -17640,0 -17641,0 -17642,0 -17643,0 -17644,0 -17645,0 -17646,0 -17647,0 -17648,0 -17649,0 -17650,0 -17651,0 -17652,0 -17653,0 -17654,0 -17655,0 -17656,0 -17657,0 -17658,0 -17659,0 -17660,0 -17661,0 -17662,0 -17663,0 -17664,0 -17665,0 -17666,0 -17667,0 -17668,0 -17669,0 -17670,0 -17671,0 -17672,0 -17673,0 -17674,0 -17675,0 -17676,0 -17677,0 -17678,0 -17679,0 -17680,0 -17681,0 -17682,0 -17683,0 -17684,0 -17685,0 -17686,0 -17687,0 -17688,0 -17689,0 -17690,0 -17691,0 -17692,0 -17693,0 -17694,0 -17695,0 -17696,0 -17697,0 -17698,0 -17699,0 -17700,0 -17701,0 -17702,0 -17703,0 -17704,0 -17705,0 -17706,0 -17707,0 -17708,0 -17709,0 -17710,0 -17711,0 -17712,0 -17713,0 -17714,0 -17715,0 -17716,0 -17717,0 -17718,0 -17719,0 -17720,0 -17721,0 -17722,0 -17723,0 -17724,0 -17725,0 -17726,0 -17727,0 -17728,0 -17729,0 -17730,0 -17731,0 -17732,0 -17733,0 -17734,0 -17735,0 -17736,0 -17737,0 -17738,0 -17739,0 -17740,0 -17741,0 -17742,0 -17743,0 -17744,0 -17745,0 -17746,0 -17747,0 -17748,0 -17749,0 -17750,0 -17751,0 -17752,0 -17753,0 -17754,0 -17755,0 -17756,0 -17757,0 -17758,0 -17759,0 -17760,0 -17761,0 -17762,0 -17763,0 -17764,0 -17765,0 -17766,0 -17767,0 -17768,0 -17769,0 -17770,0 -17771,0 -17772,0 -17773,0 -17774,0 -17775,0 -17776,0 -17777,0 -17778,0 -17779,0 -17780,0 -17781,0 -17782,0 -17783,0 -17784,0 -17785,0 -17786,0 -17787,0 -17788,0 -17789,0 -17790,0 -17791,0 -17792,0 -17793,0 -17794,0 -17795,0 -17796,0 -17797,0 -17798,0 -17799,0 -17800,0 -17801,0 -17802,0 -17803,0 -17804,0 -17805,0 -17806,0 -17807,0 -17808,0 -17809,0 -17810,0 -17811,0 -17812,0 -17813,0 -17814,0 -17815,0 -17816,0 -17817,0 -17818,0 -17819,0 -17820,0 -17821,0 -17822,0 -17823,0 -17824,0 -17825,0 -17826,0 -17827,0 -17828,0 -17829,0 -17830,0 -17831,0 -17832,0 -17833,0 -17834,0 -17835,0 -17836,0 -17837,0 -17838,0 -17839,0 -17840,0 -17841,0 -17842,0 -17843,0 -17844,0 -17845,0 -17846,0 -17847,0 -17848,0 -17849,0 -17850,0 -17851,0 -17852,0 -17853,0 -17854,0 -17855,0 -17856,0 -17857,0 -17858,0 -17859,0 -17860,0 -17861,0 -17862,0 -17863,0 -17864,0 -17865,0 -17866,0 -17867,0 -17868,0 -17869,0 -17870,0 -17871,0 -17872,0 -17873,0 -17874,0 -17875,0 -17876,0 -17877,0 -17878,0 -17879,0 -17880,0 -17881,0 -17882,0 -17883,0 -17884,0 -17885,0 -17886,0 -17887,0 -17888,0 -17889,0 -17890,0 -17891,0 -17892,0 -17893,0 -17894,0 -17895,0 -17896,0 -17897,0 -17898,0 -17899,0 -17900,0 -17901,0 -17902,0 -17903,0 -17904,0 -17905,0 -17906,0 -17907,0 -17908,0 -17909,0 -17910,0 -17911,0 -17912,0 -17913,0 -17914,0 -17915,0 -17916,0 -17917,0 -17918,0 -17919,0 -17920,0 -17921,0 -17922,0 -17923,0 -17924,0 -17925,0 -17926,0 -17927,0 -17928,0 -17929,0 -17930,0 -17931,0 -17932,0 -17933,0 -17934,0 -17935,0 -17936,0 -17937,0 -17938,0 -17939,0 -17940,0 -17941,0 -17942,0 -17943,0 -17944,0 -17945,0 -17946,0 -17947,0 -17948,0 -17949,0 -17950,0 -17951,0 -17952,0 -17953,0 -17954,0 -17955,0 -17956,0 -17957,0 -17958,0 -17959,0 -17960,0 -17961,0 -17962,0 -17963,0 -17964,0 -17965,0 -17966,0 -17967,0 -17968,0 -17969,0 -17970,0 -17971,0 -17972,0 -17973,0 -17974,0 -17975,0 -17976,0 -17977,0 -17978,0 -17979,0 -17980,0 -17981,0 -17982,0 -17983,0 -17984,0 -17985,0 -17986,0 -17987,0 -17988,0 -17989,0 -17990,0 -17991,0 -17992,0 -17993,0 -17994,0 -17995,0 -17996,0 -17997,0 -17998,0 -17999,0 -18000,0 -18001,0 -18002,0 -18003,0 -18004,0 -18005,0 -18006,0 -18007,0 -18008,0 -18009,0 -18010,0 -18011,0 -18012,0 -18013,0 -18014,0 -18015,0 -18016,0 -18017,0 -18018,0 -18019,0 -18020,0 -18021,0 -18022,0 -18023,0 -18024,0 -18025,0 -18026,0 -18027,0 -18028,0 -18029,0 -18030,0 -18031,0 -18032,0 -18033,0 -18034,0 -18035,0 -18036,0 -18037,0 -18038,0 -18039,0 -18040,0 -18041,0 -18042,0 -18043,0 -18044,0 -18045,0 -18046,0 -18047,0 -18048,0 -18049,0 -18050,0 -18051,0 -18052,0 -18053,0 -18054,0 -18055,0 -18056,0 -18057,0 -18058,0 -18059,0 -18060,0 -18061,0 -18062,0 -18063,0 -18064,0 -18065,0 -18066,0 -18067,0 -18068,0 -18069,0 -18070,0 -18071,0 -18072,0 -18073,0 -18074,0 -18075,0 -18076,0 -18077,0 -18078,0 -18079,0 -18080,0 -18081,0 -18082,0 -18083,0 -18084,0 -18085,0 -18086,0 -18087,0 -18088,0 -18089,0 -18090,0 -18091,0 -18092,0 -18093,0 -18094,0 -18095,0 -18096,0 -18097,0 -18098,0 -18099,0 -18100,0 -18101,0 -18102,0 -18103,0 -18104,0 -18105,0 -18106,0 -18107,0 -18108,0 -18109,0 -18110,0 -18111,0 -18112,0 -18113,0 -18114,0 -18115,0 -18116,0 -18117,0 -18118,0 -18119,0 -18120,0 -18121,0 -18122,0 -18123,0 -18124,0 -18125,0 -18126,0 -18127,0 -18128,0 -18129,0 -18130,0 -18131,0 -18132,0 -18133,0 -18134,0 -18135,0 -18136,0 -18137,0 -18138,0 -18139,0 -18140,0 -18141,0 -18142,0 -18143,0 -18144,0 -18145,0 -18146,0 -18147,0 -18148,0 -18149,0 -18150,0 -18151,0 -18152,0 -18153,0 -18154,0 -18155,0 -18156,0 -18157,0 -18158,0 -18159,0 -18160,0 -18161,0 -18162,0 -18163,0 -18164,0 -18165,0 -18166,0 -18167,0 -18168,0 -18169,0 -18170,0 -18171,0 -18172,0 -18173,0 -18174,0 -18175,0 -18176,0 -18177,0 -18178,0 -18179,0 -18180,0 -18181,0 -18182,0 -18183,0 -18184,0 -18185,0 -18186,0 -18187,0 -18188,0 -18189,0 -18190,0 -18191,0 -18192,0 -18193,0 -18194,0 -18195,0 -18196,0 -18197,0 -18198,0 -18199,0 -18200,0 -18201,0 -18202,0 -18203,0 -18204,0 -18205,0 -18206,0 -18207,0 -18208,0 -18209,0 -18210,0 -18211,0 -18212,0 -18213,0 -18214,0 -18215,0 -18216,0 -18217,0 -18218,0 -18219,0 -18220,0 -18221,0 -18222,0 -18223,0 -18224,0 -18225,0 -18226,0 -18227,0 -18228,0 -18229,0 -18230,0 -18231,0 -18232,0 -18233,0 -18234,0 -18235,0 -18236,0 -18237,0 -18238,0 -18239,0 -18240,0 -18241,0 -18242,0 -18243,0 -18244,0 -18245,0 -18246,0 -18247,0 -18248,0 -18249,0 -18250,0 -18251,0 -18252,0 -18253,0 -18254,0 -18255,0 -18256,0 -18257,0 -18258,0 -18259,0 -18260,0 -18261,0 -18262,0 -18263,0 -18264,0 -18265,0 -18266,0 -18267,0 -18268,0 -18269,0 -18270,0 -18271,0 -18272,0 -18273,0 -18274,0 -18275,0 -18276,0 -18277,0 -18278,0 -18279,0 -18280,0 -18281,0 -18282,0 -18283,0 -18284,0 -18285,0 -18286,0 -18287,0 -18288,0 -18289,0 -18290,0 -18291,0 -18292,0 -18293,0 -18294,0 -18295,0 -18296,0 -18297,0 -18298,0 -18299,0 -18300,0 -18301,0 -18302,0 -18303,0 -18304,0 -18305,0 -18306,0 -18307,0 -18308,0 -18309,0 -18310,0 -18311,0 -18312,0 -18313,0 -18314,0 -18315,0 -18316,0 -18317,0 -18318,0 -18319,0 -18320,0 -18321,0 -18322,0 -18323,0 -18324,0 -18325,0 -18326,0 -18327,0 -18328,0 -18329,0 -18330,0 -18331,0 -18332,0 -18333,0 -18334,0 -18335,0 -18336,0 -18337,0 -18338,0 -18339,0 -18340,0 -18341,0 -18342,0 -18343,0 -18344,0 -18345,0 -18346,0 -18347,0 -18348,0 -18349,0 -18350,0 -18351,0 -18352,0 -18353,0 -18354,0 -18355,0 -18356,0 -18357,0 -18358,0 -18359,0 -18360,0 -18361,0 -18362,0 -18363,0 -18364,0 -18365,0 -18366,0 -18367,0 -18368,0 -18369,0 -18370,0 -18371,0 -18372,0 -18373,0 -18374,0 -18375,0 -18376,0 -18377,0 -18378,0 -18379,0 -18380,0 -18381,0 -18382,0 -18383,0 -18384,0 -18385,0 -18386,0 -18387,0 -18388,0 -18389,0 -18390,0 -18391,0 -18392,0 -18393,0 -18394,0 -18395,0 -18396,0 -18397,0 -18398,0 -18399,0 -18400,0 -18401,0 -18402,0 -18403,0 -18404,0 -18405,0 -18406,0 -18407,0 -18408,0 -18409,0 -18410,0 -18411,0 -18412,0 -18413,0 -18414,0 -18415,0 -18416,0 -18417,0 -18418,0 -18419,0 -18420,0 -18421,0 -18422,0 -18423,0 -18424,0 -18425,0 -18426,0 -18427,0 -18428,0 -18429,0 -18430,0 -18431,0 -18432,0 -18433,0 -18434,0 -18435,0 -18436,0 -18437,0 -18438,0 -18439,0 -18440,0 -18441,0 -18442,0 -18443,0 -18444,0 -18445,0 -18446,0 -18447,0 -18448,0 -18449,0 -18450,0 -18451,0 -18452,0 -18453,0 -18454,0 -18455,0 -18456,0 -18457,0 -18458,0 -18459,0 -18460,0 -18461,0 -18462,0 -18463,0 -18464,0 -18465,0 -18466,0 -18467,0 -18468,0 -18469,0 -18470,0 -18471,0 -18472,0 -18473,0 -18474,0 -18475,0 -18476,0 -18477,0 -18478,0 -18479,0 -18480,0 -18481,0 -18482,0 -18483,0 -18484,0 -18485,0 -18486,0 -18487,0 -18488,0 -18489,0 -18490,0 -18491,0 -18492,0 -18493,0 -18494,0 -18495,0 -18496,0 -18497,0 -18498,0 -18499,0 -18500,0 -18501,0 -18502,0 -18503,0 -18504,0 -18505,0 -18506,0 -18507,0 -18508,0 -18509,0 -18510,0 -18511,0 -18512,0 -18513,0 -18514,0 -18515,0 -18516,0 -18517,0 -18518,0 -18519,0 -18520,0 -18521,0 -18522,0 -18523,0 -18524,0 -18525,0 -18526,0 -18527,0 -18528,0 -18529,0 -18530,0 -18531,0 -18532,0 -18533,0 -18534,0 -18535,0 -18536,0 -18537,0 -18538,0 -18539,0 -18540,0 -18541,0 -18542,0 -18543,0 -18544,0 -18545,0 -18546,0 -18547,0 -18548,0 -18549,0 -18550,0 -18551,0 -18552,0 -18553,0 -18554,0 -18555,0 -18556,0 -18557,0 -18558,0 -18559,0 -18560,0 -18561,0 -18562,0 -18563,0 -18564,0 -18565,0 -18566,0 -18567,0 -18568,0 -18569,0 -18570,0 -18571,0 -18572,0 -18573,0 -18574,0 -18575,0 -18576,0 -18577,0 -18578,0 -18579,0 -18580,0 -18581,0 -18582,0 -18583,0 -18584,0 -18585,0 -18586,0 -18587,0 -18588,0 -18589,0 -18590,0 -18591,0 -18592,0 -18593,0 -18594,0 -18595,0 -18596,0 -18597,0 -18598,0 -18599,0 -18600,0 -18601,0 -18602,0 -18603,0 -18604,0 -18605,0 -18606,0 -18607,0 -18608,0 -18609,0 -18610,0 -18611,0 -18612,0 -18613,0 -18614,0 -18615,0 -18616,0 -18617,0 -18618,0 -18619,0 -18620,0 -18621,0 -18622,0 -18623,0 -18624,0 -18625,0 -18626,0 -18627,0 -18628,0 -18629,0 -18630,0 -18631,0 -18632,0 -18633,0 -18634,0 -18635,0 -18636,0 -18637,0 -18638,0 -18639,0 -18640,0 -18641,0 -18642,0 -18643,0 -18644,0 -18645,0 -18646,0 -18647,0 -18648,0 -18649,0 -18650,0 -18651,0 -18652,0 -18653,0 -18654,0 -18655,0 -18656,0 -18657,0 -18658,0 -18659,0 -18660,0 -18661,0 -18662,0 -18663,0 -18664,0 -18665,0 -18666,0 -18667,0 -18668,0 -18669,0 -18670,0 -18671,0 -18672,0 -18673,0 -18674,0 -18675,0 -18676,0 -18677,0 -18678,0 -18679,0 -18680,0 -18681,0 -18682,0 -18683,0 -18684,0 -18685,0 -18686,0 -18687,0 -18688,0 -18689,0 -18690,0 -18691,0 -18692,0 -18693,0 -18694,0 -18695,0 -18696,0 -18697,0 -18698,0 -18699,0 -18700,0 -18701,0 -18702,0 -18703,0 -18704,0 -18705,0 -18706,0 -18707,0 -18708,0 -18709,0 -18710,0 -18711,0 -18712,0 -18713,0 -18714,0 -18715,0 -18716,0 -18717,0 -18718,0 -18719,0 -18720,0 -18721,0 -18722,0 -18723,0 -18724,0 -18725,0 -18726,0 -18727,0 -18728,0 -18729,0 -18730,0 -18731,0 -18732,0 -18733,0 -18734,0 -18735,0 -18736,0 -18737,0 -18738,0 -18739,0 -18740,0 -18741,0 -18742,0 -18743,0 -18744,0 -18745,0 -18746,0 -18747,0 -18748,0 -18749,0 -18750,0 -18751,0 -18752,0 -18753,0 -18754,0 -18755,0 -18756,0 -18757,0 -18758,0 -18759,0 -18760,0 -18761,0 -18762,0 -18763,0 -18764,0 -18765,0 -18766,0 -18767,0 -18768,0 -18769,0 -18770,0 -18771,0 -18772,0 -18773,0 -18774,0 -18775,0 -18776,0 -18777,0 -18778,0 -18779,0 -18780,0 -18781,0 -18782,0 -18783,0 -18784,0 -18785,0 -18786,0 -18787,0 -18788,0 -18789,0 -18790,0 -18791,0 -18792,0 -18793,0 -18794,0 -18795,0 -18796,0 -18797,0 -18798,0 -18799,0 -18800,0 -18801,0 -18802,0 -18803,0 -18804,0 -18805,0 -18806,0 -18807,0 -18808,0 -18809,0 -18810,0 -18811,0 -18812,0 -18813,0 -18814,0 -18815,0 -18816,0 -18817,0 -18818,0 -18819,0 -18820,0 -18821,0 -18822,0 -18823,0 -18824,0 -18825,0 -18826,0 -18827,0 -18828,0 -18829,0 -18830,0 -18831,0 -18832,0 -18833,0 -18834,0 -18835,0 -18836,0 -18837,0 -18838,0 -18839,0 -18840,0 -18841,0 -18842,0 -18843,0 -18844,0 -18845,0 -18846,0 -18847,0 -18848,0 -18849,0 -18850,0 -18851,0 -18852,0 -18853,0 -18854,0 -18855,0 -18856,0 -18857,0 -18858,0 -18859,0 -18860,0 -18861,0 -18862,0 -18863,0 -18864,0 -18865,0 -18866,0 -18867,0 -18868,0 -18869,0 -18870,0 -18871,0 -18872,0 -18873,0 -18874,0 -18875,0 -18876,0 -18877,0 -18878,0 -18879,0 -18880,0 -18881,0 -18882,0 -18883,0 -18884,0 -18885,0 -18886,0 -18887,0 -18888,0 -18889,0 -18890,0 -18891,0 -18892,0 -18893,0 -18894,0 -18895,0 -18896,0 -18897,0 -18898,0 -18899,0 -18900,0 -18901,0 -18902,0 -18903,0 -18904,0 -18905,0 -18906,0 -18907,0 -18908,0 -18909,0 -18910,0 -18911,0 -18912,0 -18913,0 -18914,0 -18915,0 -18916,0 -18917,0 -18918,0 -18919,0 -18920,0 -18921,0 -18922,0 -18923,0 -18924,0 -18925,0 -18926,0 -18927,0 -18928,0 -18929,0 -18930,0 -18931,0 -18932,0 -18933,0 -18934,0 -18935,0 -18936,0 -18937,0 -18938,0 -18939,0 -18940,0 -18941,0 -18942,0 -18943,0 -18944,0 -18945,0 -18946,0 -18947,0 -18948,0 -18949,0 -18950,0 -18951,0 -18952,0 -18953,0 -18954,0 -18955,0 -18956,0 -18957,0 -18958,0 -18959,0 -18960,0 -18961,0 -18962,0 -18963,0 -18964,0 -18965,0 -18966,0 -18967,0 -18968,0 -18969,0 -18970,0 -18971,0 -18972,0 -18973,0 -18974,0 -18975,0 -18976,0 -18977,0 -18978,0 -18979,0 -18980,0 -18981,0 -18982,0 -18983,0 -18984,0 -18985,0 -18986,0 -18987,0 -18988,0 -18989,0 -18990,0 -18991,0 -18992,0 -18993,0 -18994,0 -18995,0 -18996,0 -18997,0 -18998,0 -18999,0 -19000,0 -19001,0 -19002,0 -19003,0 -19004,0 -19005,0 -19006,0 -19007,0 -19008,0 -19009,0 -19010,0 -19011,0 -19012,0 -19013,0 -19014,0 -19015,0 -19016,0 -19017,0 -19018,0 -19019,0 -19020,0 -19021,0 -19022,0 -19023,0 -19024,0 -19025,0 -19026,0 -19027,0 -19028,0 -19029,0 -19030,0 -19031,0 -19032,0 -19033,0 -19034,0 -19035,0 -19036,0 -19037,0 -19038,0 -19039,0 -19040,0 -19041,0 -19042,0 -19043,0 -19044,0 -19045,0 -19046,0 -19047,0 -19048,0 -19049,0 -19050,0 -19051,0 -19052,0 -19053,0 -19054,0 -19055,0 -19056,0 -19057,0 -19058,0 -19059,0 -19060,0 -19061,0 -19062,0 -19063,0 -19064,0 -19065,0 -19066,0 -19067,0 -19068,0 -19069,0 -19070,0 -19071,0 -19072,0 -19073,0 -19074,0 -19075,0 -19076,0 -19077,0 -19078,0 -19079,0 -19080,0 -19081,0 -19082,0 -19083,0 -19084,0 -19085,0 -19086,0 -19087,0 -19088,0 -19089,0 -19090,0 -19091,0 -19092,0 -19093,0 -19094,0 -19095,0 -19096,0 -19097,0 -19098,0 -19099,0 -19100,0 -19101,0 -19102,0 -19103,0 -19104,0 -19105,0 -19106,0 -19107,0 -19108,0 -19109,0 -19110,0 -19111,0 -19112,0 -19113,0 -19114,0 -19115,0 -19116,0 -19117,0 -19118,0 -19119,0 -19120,0 -19121,0 -19122,0 -19123,0 -19124,0 -19125,0 -19126,0 -19127,0 -19128,0 -19129,0 -19130,0 -19131,0 -19132,0 -19133,0 -19134,0 -19135,0 -19136,0 -19137,0 -19138,0 -19139,0 -19140,0 -19141,0 -19142,0 -19143,0 -19144,0 -19145,0 -19146,0 -19147,0 -19148,0 -19149,0 -19150,0 -19151,0 -19152,0 -19153,0 -19154,0 -19155,0 -19156,0 -19157,0 -19158,0 -19159,0 -19160,0 -19161,0 -19162,0 -19163,0 -19164,0 -19165,0 -19166,0 -19167,0 -19168,0 -19169,0 -19170,0 -19171,0 -19172,0 -19173,0 -19174,0 -19175,0 -19176,0 -19177,0 -19178,0 -19179,0 -19180,0 -19181,0 -19182,0 -19183,0 -19184,0 -19185,0 -19186,0 -19187,0 -19188,0 -19189,0 -19190,0 -19191,0 -19192,0 -19193,0 -19194,0 -19195,0 -19196,0 -19197,0 -19198,0 -19199,0 -19200,0 -19201,0 -19202,0 -19203,0 -19204,0 -19205,0 -19206,0 -19207,0 -19208,0 -19209,0 -19210,0 -19211,0 -19212,0 -19213,0 -19214,0 -19215,0 -19216,0 -19217,0 -19218,0 -19219,0 -19220,0 -19221,0 -19222,0 -19223,0 -19224,0 -19225,0 -19226,0 -19227,0 -19228,0 -19229,0 -19230,0 -19231,0 -19232,0 -19233,0 -19234,0 -19235,0 -19236,0 -19237,0 -19238,0 -19239,0 -19240,0 -19241,0 -19242,0 -19243,0 -19244,0 -19245,0 -19246,0 -19247,0 -19248,0 -19249,0 -19250,0 -19251,0 -19252,0 -19253,0 -19254,0 -19255,0 -19256,0 -19257,0 -19258,0 -19259,0 -19260,0 -19261,0 -19262,0 -19263,0 -19264,0 -19265,0 -19266,0 -19267,0 -19268,0 -19269,0 -19270,0 -19271,0 -19272,0 -19273,0 -19274,0 -19275,0 -19276,0 -19277,0 -19278,0 -19279,0 -19280,0 -19281,0 -19282,0 -19283,0 -19284,0 -19285,0 -19286,0 -19287,0 -19288,0 -19289,0 -19290,0 -19291,0 -19292,0 -19293,0 -19294,0 -19295,0 -19296,0 -19297,0 -19298,0 -19299,0 -19300,0 -19301,0 -19302,0 -19303,0 -19304,0 -19305,0 -19306,0 -19307,0 -19308,0 -19309,0 -19310,0 -19311,0 -19312,0 -19313,0 -19314,0 -19315,0 -19316,0 -19317,0 -19318,0 -19319,0 -19320,0 -19321,0 -19322,0 -19323,0 -19324,0 -19325,0 -19326,0 -19327,0 -19328,0 -19329,0 -19330,0 -19331,0 -19332,0 -19333,0 -19334,0 -19335,0 -19336,0 -19337,0 -19338,0 -19339,0 -19340,0 -19341,0 -19342,0 -19343,0 -19344,0 -19345,0 -19346,0 -19347,0 -19348,0 -19349,0 -19350,0 -19351,0 -19352,0 -19353,0 -19354,0 -19355,0 -19356,0 -19357,0 -19358,0 -19359,0 -19360,0 -19361,0 -19362,0 -19363,0 -19364,0 -19365,0 -19366,0 -19367,0 -19368,0 -19369,0 -19370,0 -19371,0 -19372,0 -19373,0 -19374,0 -19375,0 -19376,0 -19377,0 -19378,0 -19379,0 -19380,0 -19381,0 -19382,0 -19383,0 -19384,0 -19385,0 -19386,0 -19387,0 -19388,0 -19389,0 -19390,0 -19391,0 -19392,0 -19393,0 -19394,0 -19395,0 -19396,0 -19397,0 -19398,0 -19399,0 -19400,0 -19401,0 -19402,0 -19403,0 -19404,0 -19405,0 -19406,0 -19407,0 -19408,0 -19409,0 -19410,0 -19411,0 -19412,0 -19413,0 -19414,0 -19415,0 -19416,0 -19417,0 -19418,0 -19419,0 -19420,0 -19421,0 -19422,0 -19423,0 -19424,0 -19425,0 -19426,0 -19427,0 -19428,0 -19429,0 -19430,0 -19431,0 -19432,0 -19433,0 -19434,0 -19435,0 -19436,0 -19437,0 -19438,0 -19439,0 -19440,0 -19441,0 -19442,0 -19443,0 -19444,0 -19445,0 -19446,0 -19447,0 -19448,0 -19449,0 -19450,0 -19451,0 -19452,0 -19453,0 -19454,0 -19455,0 -19456,0 -19457,0 -19458,0 -19459,0 -19460,0 -19461,0 -19462,0 -19463,0 -19464,0 -19465,0 -19466,0 -19467,0 -19468,0 -19469,0 -19470,0 -19471,0 -19472,0 -19473,0 -19474,0 -19475,0 -19476,0 -19477,0 -19478,0 -19479,0 -19480,0 -19481,0 -19482,0 -19483,0 -19484,0 -19485,0 -19486,0 -19487,0 -19488,0 -19489,0 -19490,0 -19491,0 -19492,0 -19493,0 -19494,0 -19495,0 -19496,0 -19497,0 -19498,0 -19499,0 -19500,0 -19501,0 -19502,0 -19503,0 -19504,0 -19505,0 -19506,0 -19507,0 -19508,0 -19509,0 -19510,0 -19511,0 -19512,0 -19513,0 -19514,0 -19515,0 -19516,0 -19517,0 -19518,0 -19519,0 -19520,0 -19521,0 -19522,0 -19523,0 -19524,0 -19525,0 -19526,0 -19527,0 -19528,0 -19529,0 -19530,0 -19531,0 -19532,0 -19533,0 -19534,0 -19535,0 -19536,0 -19537,0 -19538,0 -19539,0 -19540,0 -19541,0 -19542,0 -19543,0 -19544,0 -19545,0 -19546,0 -19547,0 -19548,0 -19549,0 -19550,0 -19551,0 -19552,0 -19553,0 -19554,0 -19555,0 -19556,0 -19557,0 -19558,0 -19559,0 -19560,0 -19561,0 -19562,0 -19563,0 -19564,0 -19565,0 -19566,0 -19567,0 -19568,0 -19569,0 -19570,0 -19571,0 -19572,0 -19573,0 -19574,0 -19575,0 -19576,0 -19577,0 -19578,0 -19579,0 -19580,0 -19581,0 -19582,0 -19583,0 -19584,0 -19585,0 -19586,0 -19587,0 -19588,0 -19589,0 -19590,0 -19591,0 -19592,0 -19593,0 -19594,0 -19595,0 -19596,0 -19597,0 -19598,0 -19599,0 -19600,0 -19601,0 -19602,0 -19603,0 -19604,0 -19605,0 -19606,0 -19607,0 -19608,0 -19609,0 -19610,0 -19611,0 -19612,0 -19613,0 -19614,0 -19615,0 -19616,0 -19617,0 -19618,0 -19619,0 -19620,0 -19621,0 -19622,0 -19623,0 -19624,0 -19625,0 -19626,0 -19627,0 -19628,0 -19629,0 -19630,0 -19631,0 -19632,0 -19633,0 -19634,0 -19635,0 -19636,0 -19637,0 -19638,0 -19639,0 -19640,0 -19641,0 -19642,0 -19643,0 -19644,0 -19645,0 -19646,0 -19647,0 -19648,0 -19649,0 -19650,0 -19651,0 -19652,0 -19653,0 -19654,0 -19655,0 -19656,0 -19657,0 -19658,0 -19659,0 -19660,0 -19661,0 -19662,0 -19663,0 -19664,0 -19665,0 -19666,0 -19667,0 -19668,0 -19669,0 -19670,0 -19671,0 -19672,0 -19673,0 -19674,0 -19675,0 -19676,0 -19677,0 -19678,0 -19679,0 -19680,0 -19681,0 -19682,0 -19683,0 -19684,0 -19685,0 -19686,0 -19687,0 -19688,0 -19689,0 -19690,0 -19691,0 -19692,0 -19693,0 -19694,0 -19695,0 -19696,0 -19697,0 -19698,0 -19699,0 -19700,0 -19701,0 -19702,0 -19703,0 -19704,0 -19705,0 -19706,0 -19707,0 -19708,0 -19709,0 -19710,0 -19711,0 -19712,0 -19713,0 -19714,0 -19715,0 -19716,0 -19717,0 -19718,0 -19719,0 -19720,0 -19721,0 -19722,0 -19723,0 -19724,0 -19725,0 -19726,0 -19727,0 -19728,0 -19729,0 -19730,0 -19731,0 -19732,0 -19733,0 -19734,0 -19735,0 -19736,0 -19737,0 -19738,0 -19739,0 -19740,0 -19741,0 -19742,0 -19743,0 -19744,0 -19745,0 -19746,0 -19747,0 -19748,0 -19749,0 -19750,0 -19751,0 -19752,0 -19753,0 -19754,0 -19755,0 -19756,0 -19757,0 -19758,0 -19759,0 -19760,0 -19761,0 -19762,0 -19763,0 -19764,0 -19765,0 -19766,0 -19767,0 -19768,0 -19769,0 -19770,0 -19771,0 -19772,0 -19773,0 -19774,0 -19775,0 -19776,0 -19777,0 -19778,0 -19779,0 -19780,0 -19781,0 -19782,0 -19783,0 -19784,0 -19785,0 -19786,0 -19787,0 -19788,0 -19789,0 -19790,0 -19791,0 -19792,0 -19793,0 -19794,0 -19795,0 -19796,0 -19797,0 -19798,0 -19799,0 -19800,0 -19801,0 -19802,0 -19803,0 -19804,0 -19805,0 -19806,0 -19807,0 -19808,0 -19809,0 -19810,0 -19811,0 -19812,0 -19813,0 -19814,0 -19815,0 -19816,0 -19817,0 -19818,0 -19819,0 -19820,0 -19821,0 -19822,0 -19823,0 -19824,0 -19825,0 -19826,0 -19827,0 -19828,0 -19829,0 -19830,0 -19831,0 -19832,0 -19833,0 -19834,0 -19835,0 -19836,0 -19837,0 -19838,0 -19839,0 -19840,0 -19841,0 -19842,0 -19843,0 -19844,0 -19845,0 -19846,0 -19847,0 -19848,0 -19849,0 -19850,0 -19851,0 -19852,0 -19853,0 -19854,0 -19855,0 -19856,0 -19857,0 -19858,0 -19859,0 -19860,0 -19861,0 -19862,0 -19863,0 -19864,0 -19865,0 -19866,0 -19867,0 -19868,0 -19869,0 -19870,0 -19871,0 -19872,0 -19873,0 -19874,0 -19875,0 -19876,0 -19877,0 -19878,0 -19879,0 -19880,0 -19881,0 -19882,0 -19883,0 -19884,0 -19885,0 -19886,0 -19887,0 -19888,0 -19889,0 -19890,0 -19891,0 -19892,0 -19893,0 -19894,0 -19895,0 -19896,0 -19897,0 -19898,0 -19899,0 -19900,0 -19901,0 -19902,0 -19903,0 -19904,0 -19905,0 -19906,0 -19907,0 -19908,0 -19909,0 -19910,0 -19911,0 -19912,0 -19913,0 -19914,0 -19915,0 -19916,0 -19917,0 -19918,0 -19919,0 -19920,0 -19921,0 -19922,0 -19923,0 -19924,0 -19925,0 -19926,0 -19927,0 -19928,0 -19929,0 -19930,0 -19931,0 -19932,0 -19933,0 -19934,0 -19935,0 -19936,0 -19937,0 -19938,0 -19939,0 -19940,0 -19941,0 -19942,0 -19943,0 -19944,0 -19945,0 -19946,0 -19947,0 -19948,0 -19949,0 -19950,0 -19951,0 -19952,0 -19953,0 -19954,0 -19955,0 -19956,0 -19957,0 -19958,0 -19959,0 -19960,0 -19961,0 -19962,0 -19963,0 -19964,0 -19965,0 -19966,0 -19967,0 -19968,0 -19969,0 -19970,0 -19971,0 -19972,0 -19973,0 -19974,0 -19975,0 -19976,0 -19977,0 -19978,0 -19979,0 -19980,0 -19981,0 -19982,0 -19983,0 -19984,0 -19985,0 -19986,0 -19987,0 -19988,0 -19989,0 -19990,0 -19991,0 -19992,0 -19993,0 -19994,0 -19995,0 -19996,0 -19997,0 -19998,0 -19999,0 -20000,0 -20001,0 -20002,0 -20003,0 -20004,0 -20005,0 -20006,0 -20007,0 -20008,0 -20009,0 -20010,0 -20011,0 -20012,0 -20013,0 -20014,0 -20015,0 -20016,0 -20017,0 -20018,0 -20019,0 -20020,0 -20021,0 -20022,0 -20023,0 -20024,0 -20025,0 -20026,0 -20027,0 -20028,0 -20029,0 -20030,0 -20031,0 -20032,0 -20033,0 -20034,0 -20035,0 -20036,0 -20037,0 -20038,0 -20039,0 -20040,0 -20041,0 -20042,0 -20043,0 -20044,0 -20045,0 -20046,0 -20047,0 -20048,0 -20049,0 -20050,0 -20051,0 -20052,0 -20053,0 -20054,0 -20055,0 -20056,0 -20057,0 -20058,0 -20059,0 -20060,0 -20061,0 -20062,0 -20063,0 -20064,0 -20065,0 -20066,0 -20067,0 -20068,0 -20069,0 -20070,0 -20071,0 -20072,0 -20073,0 -20074,0 -20075,0 -20076,0 -20077,0 -20078,0 -20079,0 -20080,0 -20081,0 -20082,0 -20083,0 -20084,0 -20085,0 -20086,0 -20087,0 -20088,0 -20089,0 -20090,0 -20091,0 -20092,0 -20093,0 -20094,0 -20095,0 -20096,0 -20097,0 -20098,0 -20099,0 -20100,0 -20101,0 -20102,0 -20103,0 -20104,0 -20105,0 -20106,0 -20107,0 -20108,0 -20109,0 -20110,0 -20111,0 -20112,0 -20113,0 -20114,0 -20115,0 -20116,0 -20117,0 -20118,0 -20119,0 -20120,0 -20121,0 -20122,0 -20123,0 -20124,0 -20125,0 -20126,0 -20127,0 -20128,0 -20129,0 -20130,0 -20131,0 -20132,0 -20133,0 -20134,0 -20135,0 -20136,0 -20137,0 -20138,0 -20139,0 -20140,0 -20141,0 -20142,0 -20143,0 -20144,0 -20145,0 -20146,0 -20147,0 -20148,0 -20149,0 -20150,0 -20151,0 -20152,0 -20153,0 -20154,0 -20155,0 -20156,0 -20157,0 -20158,0 -20159,0 -20160,0 -20161,0 -20162,0 -20163,0 -20164,0 -20165,0 -20166,0 -20167,0 -20168,0 -20169,0 -20170,0 -20171,0 -20172,0 -20173,0 -20174,0 -20175,0 -20176,0 -20177,0 -20178,0 -20179,0 -20180,0 -20181,0 -20182,0 -20183,0 -20184,0 -20185,0 -20186,0 -20187,0 -20188,0 -20189,0 -20190,0 -20191,0 -20192,0 -20193,0 -20194,0 -20195,0 -20196,0 -20197,0 -20198,0 -20199,0 -20200,0 -20201,0 -20202,0 -20203,0 -20204,0 -20205,0 -20206,0 -20207,0 -20208,0 -20209,0 -20210,0 -20211,0 -20212,0 -20213,0 -20214,0 -20215,0 -20216,0 -20217,0 -20218,0 -20219,0 -20220,0 -20221,0 -20222,0 -20223,0 -20224,0 -20225,0 -20226,0 -20227,0 -20228,0 -20229,0 -20230,0 -20231,0 -20232,0 -20233,0 -20234,0 -20235,0 -20236,0 -20237,0 -20238,0 -20239,0 -20240,0 -20241,0 -20242,0 -20243,0 -20244,0 -20245,0 -20246,0 -20247,0 -20248,0 -20249,0 -20250,0 -20251,0 -20252,0 -20253,0 -20254,0 -20255,0 -20256,0 -20257,0 -20258,0 -20259,0 -20260,0 -20261,0 -20262,0 -20263,0 -20264,0 -20265,0 -20266,0 -20267,0 -20268,0 -20269,0 -20270,0 -20271,0 -20272,0 -20273,0 -20274,0 -20275,0 -20276,0 -20277,0 -20278,0 -20279,0 -20280,0 -20281,0 -20282,0 -20283,0 -20284,0 -20285,0 -20286,0 -20287,0 -20288,0 -20289,0 -20290,0 -20291,0 -20292,0 -20293,0 -20294,0 -20295,0 -20296,0 -20297,0 -20298,0 -20299,0 -20300,0 -20301,0 -20302,0 -20303,0 -20304,0 -20305,0 -20306,0 -20307,0 -20308,0 -20309,0 -20310,0 -20311,0 -20312,0 -20313,0 -20314,0 -20315,0 -20316,0 -20317,0 -20318,0 -20319,0 -20320,0 -20321,0 -20322,0 -20323,0 -20324,0 -20325,0 -20326,0 -20327,0 -20328,0 -20329,0 -20330,0 -20331,0 -20332,0 -20333,0 -20334,0 -20335,0 -20336,0 -20337,0 -20338,0 -20339,0 -20340,0 -20341,0 -20342,0 -20343,0 -20344,0 -20345,0 -20346,0 -20347,0 -20348,0 -20349,0 -20350,0 -20351,0 -20352,0 -20353,0 -20354,0 -20355,0 -20356,0 -20357,0 -20358,0 -20359,0 -20360,0 -20361,0 -20362,0 -20363,0 -20364,0 -20365,0 -20366,0 -20367,0 -20368,0 -20369,0 -20370,0 -20371,0 -20372,0 -20373,0 -20374,0 -20375,0 -20376,0 -20377,0 -20378,0 -20379,0 -20380,0 -20381,0 -20382,0 -20383,0 -20384,0 -20385,0 -20386,0 -20387,0 -20388,0 -20389,0 -20390,0 -20391,0 -20392,0 -20393,0 -20394,0 -20395,0 -20396,0 -20397,0 -20398,0 -20399,0 -20400,0 -20401,0 -20402,0 -20403,0 -20404,0 -20405,0 -20406,0 -20407,0 -20408,0 -20409,0 -20410,0 -20411,0 -20412,0 -20413,0 -20414,0 -20415,0 -20416,0 -20417,0 -20418,0 -20419,0 -20420,0 -20421,0 -20422,0 -20423,0 -20424,0 -20425,0 -20426,0 -20427,0 -20428,0 -20429,0 -20430,0 -20431,0 -20432,0 -20433,0 -20434,0 -20435,0 -20436,0 -20437,0 -20438,0 -20439,0 -20440,0 -20441,0 -20442,0 -20443,0 -20444,0 -20445,0 -20446,0 -20447,0 -20448,0 -20449,0 -20450,0 -20451,0 -20452,0 -20453,0 -20454,0 -20455,0 -20456,0 -20457,0 -20458,0 -20459,0 -20460,0 -20461,0 -20462,0 -20463,0 -20464,0 -20465,0 -20466,0 -20467,0 -20468,0 -20469,0 -20470,0 -20471,0 -20472,0 -20473,0 -20474,0 -20475,0 -20476,0 -20477,0 -20478,0 -20479,0 -20480,0 -20481,0 -20482,0 -20483,0 -20484,0 -20485,0 -20486,0 -20487,0 -20488,0 -20489,0 -20490,0 -20491,0 -20492,0 -20493,0 -20494,0 -20495,0 -20496,0 -20497,0 -20498,0 -20499,0 -20500,0 -20501,0 -20502,0 -20503,0 -20504,0 -20505,0 -20506,0 -20507,0 -20508,0 -20509,0 -20510,0 -20511,0 -20512,0 -20513,0 -20514,0 -20515,0 -20516,0 -20517,0 -20518,0 -20519,0 -20520,0 -20521,0 -20522,0 -20523,0 -20524,0 -20525,0 -20526,0 -20527,0 -20528,0 -20529,0 -20530,0 -20531,0 -20532,0 -20533,0 -20534,0 -20535,0 -20536,0 -20537,0 -20538,0 -20539,0 -20540,0 -20541,0 -20542,0 -20543,0 -20544,0 -20545,0 -20546,0 -20547,0 -20548,0 -20549,0 -20550,0 -20551,0 -20552,0 -20553,0 -20554,0 -20555,0 -20556,0 -20557,0 -20558,0 -20559,0 -20560,0 -20561,0 -20562,0 -20563,0 -20564,0 -20565,0 -20566,0 -20567,0 -20568,0 -20569,0 -20570,0 -20571,0 -20572,0 -20573,0 -20574,0 -20575,0 -20576,0 -20577,0 -20578,0 -20579,0 -20580,0 -20581,0 -20582,0 -20583,0 -20584,0 -20585,0 -20586,0 -20587,0 -20588,0 -20589,0 -20590,0 -20591,0 -20592,0 -20593,0 -20594,0 -20595,0 -20596,0 -20597,0 -20598,0 -20599,0 -20600,0 -20601,0 -20602,0 -20603,0 -20604,0 -20605,0 -20606,0 -20607,0 -20608,0 -20609,0 -20610,0 -20611,0 -20612,0 -20613,0 -20614,0 -20615,0 -20616,0 -20617,0 -20618,0 -20619,0 -20620,0 -20621,0 -20622,0 -20623,0 -20624,0 -20625,0 -20626,0 -20627,0 -20628,0 -20629,0 -20630,0 -20631,0 -20632,0 -20633,0 -20634,0 -20635,0 -20636,0 -20637,0 -20638,0 -20639,0 -20640,0 -20641,0 -20642,0 -20643,0 -20644,0 -20645,0 -20646,0 -20647,0 -20648,0 -20649,0 -20650,0 -20651,0 -20652,0 -20653,0 -20654,0 -20655,0 -20656,0 -20657,0 -20658,0 -20659,0 -20660,0 -20661,0 -20662,0 -20663,0 -20664,0 -20665,0 -20666,0 -20667,0 -20668,0 -20669,0 -20670,0 -20671,0 -20672,0 -20673,0 -20674,0 -20675,0 -20676,0 -20677,0 -20678,0 -20679,0 -20680,0 -20681,0 -20682,0 -20683,0 -20684,0 -20685,0 -20686,0 -20687,0 -20688,0 -20689,0 -20690,0 -20691,0 -20692,0 -20693,0 -20694,0 -20695,0 -20696,0 -20697,0 -20698,0 -20699,0 -20700,0 -20701,0 -20702,0 -20703,0 -20704,0 -20705,0 -20706,0 -20707,0 -20708,0 -20709,0 -20710,0 -20711,0 -20712,0 -20713,0 -20714,0 -20715,0 -20716,0 -20717,0 -20718,0 -20719,0 -20720,0 -20721,0 -20722,0 -20723,0 -20724,0 -20725,0 -20726,0 -20727,0 -20728,0 -20729,0 -20730,0 -20731,0 -20732,0 -20733,0 -20734,0 -20735,0 -20736,0 -20737,0 -20738,0 -20739,0 -20740,0 -20741,0 -20742,0 -20743,0 -20744,0 -20745,0 -20746,0 -20747,0 -20748,0 -20749,0 -20750,0 -20751,0 -20752,0 -20753,0 -20754,0 -20755,0 -20756,0 -20757,0 -20758,0 -20759,0 -20760,0 -20761,0 -20762,0 -20763,0 -20764,0 -20765,0 -20766,0 -20767,0 -20768,0 -20769,0 -20770,0 -20771,0 -20772,0 -20773,0 -20774,0 -20775,0 -20776,0 -20777,0 -20778,0 -20779,0 -20780,0 -20781,0 -20782,0 -20783,0 -20784,0 -20785,0 -20786,0 -20787,0 -20788,0 -20789,0 -20790,0 -20791,0 -20792,0 -20793,0 -20794,0 -20795,0 -20796,0 -20797,0 -20798,0 -20799,0 -20800,0 -20801,0 -20802,0 -20803,0 -20804,0 -20805,0 -20806,0 -20807,0 -20808,0 -20809,0 -20810,0 -20811,0 -20812,0 -20813,0 -20814,0 -20815,0 -20816,0 -20817,0 -20818,0 -20819,0 -20820,0 -20821,0 -20822,0 -20823,0 -20824,0 -20825,0 -20826,0 -20827,0 -20828,0 -20829,0 -20830,0 -20831,0 -20832,0 -20833,0 -20834,0 -20835,0 -20836,0 -20837,0 -20838,0 -20839,0 -20840,0 -20841,0 -20842,0 -20843,0 -20844,0 -20845,0 -20846,0 -20847,0 -20848,0 -20849,0 -20850,0 -20851,0 -20852,0 -20853,0 -20854,0 -20855,0 -20856,0 -20857,0 -20858,0 -20859,0 -20860,0 -20861,0 -20862,0 -20863,0 -20864,0 -20865,0 -20866,0 -20867,0 -20868,0 -20869,0 -20870,0 -20871,0 -20872,0 -20873,0 -20874,0 -20875,0 -20876,0 -20877,0 -20878,0 -20879,0 -20880,0 -20881,0 -20882,0 -20883,0 -20884,0 -20885,0 -20886,0 -20887,0 -20888,0 -20889,0 -20890,0 -20891,0 -20892,0 -20893,0 -20894,0 -20895,0 -20896,0 -20897,0 -20898,0 -20899,0 -20900,0 -20901,0 -20902,0 -20903,0 -20904,0 -20905,0 -20906,0 -20907,0 -20908,0 -20909,0 -20910,0 -20911,0 -20912,0 -20913,0 -20914,0 -20915,0 -20916,0 -20917,0 -20918,0 -20919,0 -20920,0 -20921,0 -20922,0 -20923,0 -20924,0 -20925,0 -20926,0 -20927,0 -20928,0 -20929,0 -20930,0 -20931,0 -20932,0 -20933,0 -20934,0 -20935,0 -20936,0 -20937,0 -20938,0 -20939,0 -20940,0 -20941,0 -20942,0 -20943,0 -20944,0 -20945,0 -20946,0 -20947,0 -20948,0 -20949,0 -20950,0 -20951,0 -20952,0 -20953,0 -20954,0 -20955,0 -20956,0 -20957,0 -20958,0 -20959,0 -20960,0 -20961,0 -20962,0 -20963,0 -20964,0 -20965,0 -20966,0 -20967,0 -20968,0 -20969,0 -20970,0 -20971,0 -20972,0 -20973,0 -20974,0 -20975,0 -20976,0 -20977,0 -20978,0 -20979,0 -20980,0 -20981,0 -20982,0 -20983,0 -20984,0 -20985,0 -20986,0 -20987,0 -20988,0 -20989,0 -20990,0 -20991,0 -20992,0 -20993,0 -20994,0 -20995,0 -20996,0 -20997,0 -20998,0 -20999,0 -21000,0 -21001,0 -21002,0 -21003,0 -21004,0 -21005,0 -21006,0 -21007,0 -21008,0 -21009,0 -21010,0 -21011,0 -21012,0 -21013,0 -21014,0 -21015,0 -21016,0 -21017,0 -21018,0 -21019,0 -21020,0 -21021,0 -21022,0 -21023,0 -21024,0 -21025,0 -21026,0 -21027,0 -21028,0 -21029,0 -21030,0 -21031,0 -21032,0 -21033,0 -21034,0 -21035,0 -21036,0 -21037,0 -21038,0 -21039,0 -21040,0 -21041,0 -21042,0 -21043,0 -21044,0 -21045,0 -21046,0 -21047,0 -21048,0 -21049,0 -21050,0 -21051,0 -21052,0 -21053,0 -21054,0 -21055,0 -21056,0 -21057,0 -21058,0 -21059,0 -21060,0 -21061,0 -21062,0 -21063,0 -21064,0 -21065,0 -21066,0 -21067,0 -21068,0 -21069,0 -21070,0 -21071,0 -21072,0 -21073,0 -21074,0 -21075,0 -21076,0 -21077,0 -21078,0 -21079,0 -21080,0 -21081,0 -21082,0 -21083,0 -21084,0 -21085,0 -21086,0 -21087,0 -21088,0 -21089,0 -21090,0 -21091,0 -21092,0 -21093,0 -21094,0 -21095,0 -21096,0 -21097,0 -21098,0 -21099,0 -21100,0 -21101,0 -21102,0 -21103,0 -21104,0 -21105,0 -21106,0 -21107,0 -21108,0 -21109,0 -21110,0 -21111,0 -21112,0 -21113,0 -21114,0 -21115,0 -21116,0 -21117,0 -21118,0 -21119,0 -21120,0 -21121,0 -21122,0 -21123,0 -21124,0 -21125,0 -21126,0 -21127,0 -21128,0 -21129,0 -21130,0 -21131,0 -21132,0 -21133,0 -21134,0 -21135,0 -21136,0 -21137,0 -21138,0 -21139,0 -21140,0 -21141,0 -21142,0 -21143,0 -21144,0 -21145,0 -21146,0 -21147,0 -21148,0 -21149,0 -21150,0 -21151,0 -21152,0 -21153,0 -21154,0 -21155,0 -21156,0 -21157,0 -21158,0 -21159,0 -21160,0 -21161,0 -21162,0 -21163,0 -21164,0 -21165,0 -21166,0 -21167,0 -21168,0 -21169,0 -21170,0 -21171,0 -21172,0 -21173,0 -21174,0 -21175,0 -21176,0 -21177,0 -21178,0 -21179,0 -21180,0 -21181,0 -21182,0 -21183,0 -21184,0 -21185,0 -21186,0 -21187,0 -21188,0 -21189,0 -21190,0 -21191,0 -21192,0 -21193,0 -21194,0 -21195,0 -21196,0 -21197,0 -21198,0 -21199,0 -21200,0 -21201,0 -21202,0 -21203,0 -21204,0 -21205,0 -21206,0 -21207,0 -21208,0 -21209,0 -21210,0 -21211,0 -21212,0 -21213,0 -21214,0 -21215,0 -21216,0 -21217,0 -21218,0 -21219,0 -21220,0 -21221,0 -21222,0 -21223,0 -21224,0 -21225,0 -21226,0 -21227,0 -21228,0 -21229,0 -21230,0 -21231,0 -21232,0 -21233,0 -21234,0 -21235,0 -21236,0 -21237,0 -21238,0 -21239,0 -21240,0 -21241,0 -21242,0 -21243,0 -21244,0 -21245,0 -21246,0 -21247,0 -21248,0 -21249,0 -21250,0 -21251,0 -21252,0 -21253,0 -21254,0 -21255,0 -21256,0 -21257,0 -21258,0 -21259,0 -21260,0 -21261,0 -21262,0 -21263,0 -21264,0 -21265,0 -21266,0 -21267,0 -21268,0 -21269,0 -21270,0 -21271,0 -21272,0 -21273,0 -21274,0 -21275,0 -21276,0 -21277,0 -21278,0 -21279,0 -21280,0 -21281,0 -21282,0 -21283,0 -21284,0 -21285,0 -21286,0 -21287,0 -21288,0 -21289,0 -21290,0 -21291,0 -21292,0 -21293,0 -21294,0 -21295,0 -21296,0 -21297,0 -21298,0 -21299,0 -21300,0 -21301,0 -21302,0 -21303,0 -21304,0 -21305,0 -21306,0 -21307,0 -21308,0 -21309,0 -21310,0 -21311,0 -21312,0 -21313,0 -21314,0 -21315,0 -21316,0 -21317,0 -21318,0 -21319,0 -21320,0 -21321,0 -21322,0 -21323,0 -21324,0 -21325,0 -21326,0 -21327,0 -21328,0 -21329,0 -21330,0 -21331,0 -21332,0 -21333,0 -21334,0 -21335,0 -21336,0 -21337,0 -21338,0 -21339,0 -21340,0 -21341,0 -21342,0 -21343,0 -21344,0 -21345,0 -21346,0 -21347,0 -21348,0 -21349,0 -21350,0 -21351,0 -21352,0 -21353,0 -21354,0 -21355,0 -21356,0 -21357,0 -21358,0 -21359,0 -21360,0 -21361,0 -21362,0 -21363,0 -21364,0 -21365,0 -21366,0 -21367,0 -21368,0 -21369,0 -21370,0 -21371,0 -21372,0 -21373,0 -21374,0 -21375,0 -21376,0 -21377,0 -21378,0 -21379,0 -21380,0 -21381,0 -21382,0 -21383,0 -21384,0 -21385,0 -21386,0 -21387,0 -21388,0 -21389,0 -21390,0 -21391,0 -21392,0 -21393,0 -21394,0 -21395,0 -21396,0 -21397,0 -21398,0 -21399,0 -21400,0 -21401,0 -21402,0 -21403,0 -21404,0 -21405,0 -21406,0 -21407,0 -21408,0 -21409,0 -21410,0 -21411,0 -21412,0 -21413,0 -21414,0 -21415,0 -21416,0 -21417,0 -21418,0 -21419,0 -21420,0 -21421,0 -21422,0 -21423,0 -21424,0 -21425,0 -21426,0 -21427,0 -21428,0 -21429,0 -21430,0 -21431,0 -21432,0 -21433,0 -21434,0 -21435,0 -21436,0 -21437,0 -21438,0 -21439,0 -21440,0 -21441,0 -21442,0 -21443,0 -21444,0 -21445,0 -21446,0 -21447,0 -21448,0 -21449,0 -21450,0 -21451,0 -21452,0 -21453,0 -21454,0 -21455,0 -21456,0 -21457,0 -21458,0 -21459,0 -21460,0 -21461,0 -21462,0 -21463,0 -21464,0 -21465,0 -21466,0 -21467,0 -21468,0 -21469,0 -21470,0 -21471,0 -21472,0 -21473,0 -21474,0 -21475,0 -21476,0 -21477,0 -21478,0 -21479,0 -21480,0 -21481,0 -21482,0 -21483,0 -21484,0 -21485,0 -21486,0 -21487,0 -21488,0 -21489,0 -21490,0 -21491,0 -21492,0 -21493,0 -21494,0 -21495,0 -21496,0 -21497,0 -21498,0 -21499,0 -21500,0 -21501,0 -21502,0 -21503,0 -21504,0 -21505,0 -21506,0 -21507,0 -21508,0 -21509,0 -21510,0 -21511,0 -21512,0 -21513,0 -21514,0 -21515,0 -21516,0 -21517,0 -21518,0 -21519,0 -21520,0 -21521,0 -21522,0 -21523,0 -21524,0 -21525,0 -21526,0 -21527,0 -21528,0 -21529,0 -21530,0 -21531,0 -21532,0 -21533,0 -21534,0 -21535,0 -21536,0 -21537,0 -21538,0 -21539,0 -21540,0 -21541,0 -21542,0 -21543,0 -21544,0 -21545,0 -21546,0 -21547,0 -21548,0 -21549,0 -21550,0 -21551,0 -21552,0 -21553,0 -21554,0 -21555,0 -21556,0 -21557,0 -21558,0 -21559,0 -21560,0 -21561,0 -21562,0 -21563,0 -21564,0 -21565,0 -21566,0 -21567,0 -21568,0 -21569,0 -21570,0 -21571,0 -21572,0 -21573,0 -21574,0 -21575,0 -21576,0 -21577,0 -21578,0 -21579,0 -21580,0 -21581,0 -21582,0 -21583,0 -21584,0 -21585,0 -21586,0 -21587,0 -21588,0 -21589,0 -21590,0 -21591,0 -21592,0 -21593,0 -21594,0 -21595,0 -21596,0 -21597,0 -21598,0 -21599,0 -21600,0 -21601,0 -21602,0 -21603,0 -21604,0 -21605,0 -21606,0 -21607,0 -21608,0 -21609,0 -21610,0 -21611,0 -21612,0 -21613,0 -21614,0 -21615,0 -21616,0 -21617,0 -21618,0 -21619,0 -21620,0 -21621,0 -21622,0 -21623,0 -21624,0 -21625,0 -21626,0 -21627,0 -21628,0 -21629,0 -21630,0 -21631,0 -21632,0 -21633,0 -21634,0 -21635,0 -21636,0 -21637,0 -21638,0 -21639,0 -21640,0 -21641,0 -21642,0 -21643,0 -21644,0 -21645,0 -21646,0 -21647,0 -21648,0 -21649,0 -21650,0 -21651,0 -21652,0 -21653,0 -21654,0 -21655,0 -21656,0 -21657,0 -21658,0 -21659,0 -21660,0 -21661,0 -21662,0 -21663,0 -21664,0 -21665,0 -21666,0 -21667,0 -21668,0 -21669,0 -21670,0 -21671,0 -21672,0 -21673,0 -21674,0 -21675,0 -21676,0 -21677,0 -21678,0 -21679,0 -21680,0 -21681,0 -21682,0 -21683,0 -21684,0 -21685,0 -21686,0 -21687,0 -21688,0 -21689,0 -21690,0 -21691,0 -21692,0 -21693,0 -21694,0 -21695,0 -21696,0 -21697,0 -21698,0 -21699,0 -21700,0 -21701,0 -21702,0 -21703,0 -21704,0 -21705,0 -21706,0 -21707,0 -21708,0 -21709,0 -21710,0 -21711,0 -21712,0 -21713,0 -21714,0 -21715,0 -21716,0 -21717,0 -21718,0 -21719,0 -21720,0 -21721,0 -21722,0 -21723,0 -21724,0 -21725,0 -21726,0 -21727,0 -21728,0 -21729,0 -21730,0 -21731,0 -21732,0 -21733,0 -21734,0 -21735,0 -21736,0 -21737,0 -21738,0 -21739,0 -21740,0 -21741,0 -21742,0 -21743,0 -21744,0 -21745,0 -21746,0 -21747,0 -21748,0 -21749,0 -21750,0 -21751,0 -21752,0 -21753,0 -21754,0 -21755,0 -21756,0 -21757,0 -21758,0 -21759,0 -21760,0 -21761,0 -21762,0 -21763,0 -21764,0 -21765,0 -21766,0 -21767,0 -21768,0 -21769,0 -21770,0 -21771,0 -21772,0 -21773,0 -21774,0 -21775,0 -21776,0 -21777,0 -21778,0 -21779,0 -21780,0 -21781,0 -21782,0 -21783,0 -21784,0 -21785,0 -21786,0 -21787,0 -21788,0 -21789,0 -21790,0 -21791,0 -21792,0 -21793,0 -21794,0 -21795,0 -21796,0 -21797,0 -21798,0 -21799,0 -21800,0 -21801,0 -21802,0 -21803,0 -21804,0 -21805,0 -21806,0 -21807,0 -21808,0 -21809,0 -21810,0 -21811,0 -21812,0 -21813,0 -21814,0 -21815,0 -21816,0 -21817,0 -21818,0 -21819,0 -21820,0 -21821,0 -21822,0 -21823,0 -21824,0 -21825,0 -21826,0 -21827,0 -21828,0 -21829,0 -21830,0 -21831,0 -21832,0 -21833,0 -21834,0 -21835,0 -21836,0 -21837,0 -21838,0 -21839,0 -21840,0 -21841,0 -21842,0 -21843,0 -21844,0 -21845,0 -21846,0 -21847,0 -21848,0 -21849,0 -21850,0 -21851,0 -21852,0 -21853,0 -21854,0 -21855,0 -21856,0 -21857,0 -21858,0 -21859,0 -21860,0 -21861,0 -21862,0 -21863,0 -21864,0 -21865,0 -21866,0 -21867,0 -21868,0 -21869,0 -21870,0 -21871,0 -21872,0 -21873,0 -21874,0 -21875,0 -21876,0 -21877,0 -21878,0 -21879,0 -21880,0 -21881,0 -21882,0 -21883,0 -21884,0 -21885,0 -21886,0 -21887,0 -21888,0 -21889,0 -21890,0 -21891,0 -21892,0 -21893,0 -21894,0 -21895,0 -21896,0 -21897,0 -21898,0 -21899,0 -21900,0 -21901,0 -21902,0 -21903,0 -21904,0 -21905,0 -21906,0 -21907,0 -21908,0 -21909,0 -21910,0 -21911,0 -21912,0 -21913,0 -21914,0 -21915,0 -21916,0 -21917,0 -21918,0 -21919,0 -21920,0 -21921,0 -21922,0 -21923,0 -21924,0 -21925,0 -21926,0 -21927,0 -21928,0 -21929,0 -21930,0 -21931,0 -21932,0 -21933,0 -21934,0 -21935,0 -21936,0 -21937,0 -21938,0 -21939,0 -21940,0 -21941,0 -21942,0 -21943,0 -21944,0 -21945,0 -21946,0 -21947,0 -21948,0 -21949,0 -21950,0 -21951,0 -21952,0 -21953,0 -21954,0 -21955,0 -21956,0 -21957,0 -21958,0 -21959,0 -21960,0 -21961,0 -21962,0 -21963,0 -21964,0 -21965,0 -21966,0 -21967,0 -21968,0 -21969,0 -21970,0 -21971,0 -21972,0 -21973,0 -21974,0 -21975,0 -21976,0 -21977,0 -21978,0 -21979,0 -21980,0 -21981,0 -21982,0 -21983,0 -21984,0 -21985,0 -21986,0 -21987,0 -21988,0 -21989,0 -21990,0 -21991,0 -21992,0 -21993,0 -21994,0 -21995,0 -21996,0 -21997,0 -21998,0 -21999,0 -22000,0 -22001,0 -22002,0 -22003,0 -22004,0 -22005,0 -22006,0 -22007,0 -22008,0 -22009,0 -22010,0 -22011,0 -22012,0 -22013,0 -22014,0 -22015,0 -22016,0 -22017,0 -22018,0 -22019,0 -22020,0 -22021,0 -22022,0 -22023,0 -22024,0 -22025,0 -22026,0 -22027,0 -22028,0 -22029,0 -22030,0 -22031,0 -22032,0 -22033,0 -22034,0 -22035,0 -22036,0 -22037,0 -22038,0 -22039,0 -22040,0 -22041,0 -22042,0 -22043,0 -22044,0 -22045,0 -22046,0 -22047,0 -22048,0 -22049,0 -22050,0 -22051,0 -22052,0 -22053,0 -22054,0 -22055,0 -22056,0 -22057,0 -22058,0 -22059,0 -22060,0 -22061,0 -22062,0 -22063,0 -22064,0 -22065,0 -22066,0 -22067,0 -22068,0 -22069,0 -22070,0 -22071,0 -22072,0 -22073,0 -22074,0 -22075,0 -22076,0 -22077,0 -22078,0 -22079,0 -22080,0 -22081,0 -22082,0 -22083,0 -22084,0 -22085,0 -22086,0 -22087,0 -22088,0 -22089,0 -22090,0 -22091,0 -22092,0 -22093,0 -22094,0 -22095,0 -22096,0 -22097,0 -22098,0 -22099,0 -22100,0 -22101,0 -22102,0 -22103,0 -22104,0 -22105,0 -22106,0 -22107,0 -22108,0 -22109,0 -22110,0 -22111,0 -22112,0 -22113,0 -22114,0 -22115,0 -22116,0 -22117,0 -22118,0 -22119,0 -22120,0 -22121,0 -22122,0 -22123,0 -22124,0 -22125,0 -22126,0 -22127,0 -22128,0 -22129,0 -22130,0 -22131,0 -22132,0 -22133,0 -22134,0 -22135,0 -22136,0 -22137,0 -22138,0 -22139,0 -22140,0 -22141,0 -22142,0 -22143,0 -22144,0 -22145,0 -22146,0 -22147,0 -22148,0 -22149,0 -22150,0 -22151,0 -22152,0 -22153,0 -22154,0 -22155,0 -22156,0 -22157,0 -22158,0 -22159,0 -22160,0 -22161,0 -22162,0 -22163,0 -22164,0 -22165,0 -22166,0 -22167,0 -22168,0 -22169,0 -22170,0 -22171,0 -22172,0 -22173,0 -22174,0 -22175,0 -22176,0 -22177,0 -22178,0 -22179,0 -22180,0 -22181,0 -22182,0 -22183,0 -22184,0 -22185,0 -22186,0 -22187,0 -22188,0 -22189,0 -22190,0 -22191,0 -22192,0 -22193,0 -22194,0 -22195,0 -22196,0 -22197,0 -22198,0 -22199,0 -22200,0 -22201,0 -22202,0 -22203,0 -22204,0 -22205,0 -22206,0 -22207,0 -22208,0 -22209,0 -22210,0 -22211,0 -22212,0 -22213,0 -22214,0 -22215,0 -22216,0 -22217,0 -22218,0 -22219,0 -22220,0 -22221,0 -22222,0 -22223,0 -22224,0 -22225,0 -22226,0 -22227,0 -22228,0 -22229,0 -22230,0 -22231,0 -22232,0 -22233,0 -22234,0 -22235,0 -22236,0 -22237,0 -22238,0 -22239,0 -22240,0 -22241,0 -22242,0 -22243,0 -22244,0 -22245,0 -22246,0 -22247,0 -22248,0 -22249,0 -22250,0 -22251,0 -22252,0 -22253,0 -22254,0 -22255,0 -22256,0 -22257,0 -22258,0 -22259,0 -22260,0 -22261,0 -22262,0 -22263,0 -22264,0 -22265,0 -22266,0 -22267,0 -22268,0 -22269,0 -22270,0 -22271,0 -22272,0 -22273,0 -22274,0 -22275,0 -22276,0 -22277,0 -22278,0 -22279,0 -22280,0 -22281,0 -22282,0 -22283,0 -22284,0 -22285,0 -22286,0 -22287,0 -22288,0 -22289,0 -22290,0 -22291,0 -22292,0 -22293,0 -22294,0 -22295,0 -22296,0 -22297,0 -22298,0 -22299,0 -22300,0 -22301,0 -22302,0 -22303,0 -22304,0 -22305,0 -22306,0 -22307,0 -22308,0 -22309,0 -22310,0 -22311,0 -22312,0 -22313,0 -22314,0 -22315,0 -22316,0 -22317,0 -22318,0 -22319,0 -22320,0 -22321,0 -22322,0 -22323,0 -22324,0 -22325,0 -22326,0 -22327,0 -22328,0 -22329,0 -22330,0 -22331,0 -22332,0 -22333,0 -22334,0 -22335,0 -22336,0 -22337,0 -22338,0 -22339,0 -22340,0 -22341,0 -22342,0 -22343,0 -22344,0 -22345,0 -22346,0 -22347,0 -22348,0 -22349,0 -22350,0 -22351,0 -22352,0 -22353,0 -22354,0 -22355,0 -22356,0 -22357,0 -22358,0 -22359,0 -22360,0 -22361,0 -22362,0 -22363,0 -22364,0 -22365,0 -22366,0 -22367,0 -22368,0 -22369,0 -22370,0 -22371,0 -22372,0 -22373,0 -22374,0 -22375,0 -22376,0 -22377,0 -22378,0 -22379,0 -22380,0 -22381,0 -22382,0 -22383,0 -22384,0 -22385,0 -22386,0 -22387,0 -22388,0 -22389,0 -22390,0 -22391,0 -22392,0 -22393,0 -22394,0 -22395,0 -22396,0 -22397,0 -22398,0 -22399,0 -22400,0 -22401,0 -22402,0 -22403,0 -22404,0 -22405,0 -22406,0 -22407,0 -22408,0 -22409,0 -22410,0 -22411,0 -22412,0 -22413,0 -22414,0 -22415,0 -22416,0 -22417,0 -22418,0 -22419,0 -22420,0 -22421,0 -22422,0 -22423,0 -22424,0 -22425,0 -22426,0 -22427,0 -22428,0 -22429,0 -22430,0 -22431,0 -22432,0 -22433,0 -22434,0 -22435,0 -22436,0 -22437,0 -22438,0 -22439,0 -22440,0 -22441,0 -22442,0 -22443,0 -22444,0 -22445,0 -22446,0 -22447,0 -22448,0 -22449,0 -22450,0 -22451,0 -22452,0 -22453,0 -22454,0 -22455,0 -22456,0 -22457,0 -22458,0 -22459,0 -22460,0 -22461,0 -22462,0 -22463,0 -22464,0 -22465,0 -22466,0 -22467,0 -22468,0 -22469,0 -22470,0 -22471,0 -22472,0 -22473,0 -22474,0 -22475,0 -22476,0 -22477,0 -22478,0 -22479,0 -22480,0 -22481,0 -22482,0 -22483,0 -22484,0 -22485,0 -22486,0 -22487,0 -22488,0 -22489,0 -22490,0 -22491,0 -22492,0 -22493,0 -22494,0 -22495,0 -22496,0 -22497,0 -22498,0 -22499,0 -22500,0 -22501,0 -22502,0 -22503,0 -22504,0 -22505,0 -22506,0 -22507,0 -22508,0 -22509,0 -22510,0 -22511,0 -22512,0 -22513,0 -22514,0 -22515,0 -22516,0 -22517,0 -22518,0 -22519,0 -22520,0 -22521,0 -22522,0 -22523,0 -22524,0 -22525,0 -22526,0 -22527,0 -22528,0 -22529,0 -22530,0 -22531,0 -22532,0 -22533,0 -22534,0 -22535,0 -22536,0 -22537,0 -22538,0 -22539,0 -22540,0 -22541,0 -22542,0 -22543,0 -22544,0 -22545,0 -22546,0 -22547,0 -22548,0 -22549,0 -22550,0 -22551,0 -22552,0 -22553,0 -22554,0 -22555,0 -22556,0 -22557,0 -22558,0 -22559,0 -22560,0 -22561,0 -22562,0 -22563,0 -22564,0 -22565,0 -22566,0 -22567,0 -22568,0 -22569,0 -22570,0 -22571,0 -22572,0 -22573,0 -22574,0 -22575,0 -22576,0 -22577,0 -22578,0 -22579,0 -22580,0 -22581,0 -22582,0 -22583,0 -22584,0 -22585,0 -22586,0 -22587,0 -22588,0 -22589,0 -22590,0 -22591,0 -22592,0 -22593,0 -22594,0 -22595,0 -22596,0 -22597,0 -22598,0 -22599,0 -22600,0 -22601,0 -22602,0 -22603,0 -22604,0 -22605,0 -22606,0 -22607,0 -22608,0 -22609,0 -22610,0 -22611,0 -22612,0 -22613,0 -22614,0 -22615,0 -22616,0 -22617,0 -22618,0 -22619,0 -22620,0 -22621,0 -22622,0 -22623,0 -22624,0 -22625,0 -22626,0 -22627,0 -22628,0 -22629,0 -22630,0 -22631,0 -22632,0 -22633,0 -22634,0 -22635,0 -22636,0 -22637,0 -22638,0 -22639,0 -22640,0 -22641,0 -22642,0 -22643,0 -22644,0 -22645,0 -22646,0 -22647,0 -22648,0 -22649,0 -22650,0 -22651,0 -22652,0 -22653,0 -22654,0 -22655,0 -22656,0 -22657,0 -22658,0 -22659,0 -22660,0 -22661,0 -22662,0 -22663,0 -22664,0 -22665,0 -22666,0 -22667,0 -22668,0 -22669,0 -22670,0 -22671,0 -22672,0 -22673,0 -22674,0 -22675,0 -22676,0 -22677,0 -22678,0 -22679,0 -22680,0 -22681,0 -22682,0 -22683,0 -22684,0 -22685,0 -22686,0 -22687,0 -22688,0 -22689,0 -22690,0 -22691,0 -22692,0 -22693,0 -22694,0 -22695,0 -22696,0 -22697,0 -22698,0 -22699,0 -22700,0 -22701,0 -22702,0 -22703,0 -22704,0 -22705,0 -22706,0 -22707,0 -22708,0 -22709,0 -22710,0 -22711,0 -22712,0 -22713,0 -22714,0 -22715,0 -22716,0 -22717,0 -22718,0 -22719,0 -22720,0 -22721,0 -22722,0 -22723,0 -22724,0 -22725,0 -22726,0 -22727,0 -22728,0 -22729,0 -22730,0 -22731,0 -22732,0 -22733,0 -22734,0 -22735,0 -22736,0 -22737,0 -22738,0 -22739,0 -22740,0 -22741,0 -22742,0 -22743,0 -22744,0 -22745,0 -22746,0 -22747,0 -22748,0 -22749,0 -22750,0 -22751,0 -22752,0 -22753,0 -22754,0 -22755,0 -22756,0 -22757,0 -22758,0 -22759,0 -22760,0 -22761,0 -22762,0 -22763,0 -22764,0 -22765,0 -22766,0 -22767,0 -22768,0 -22769,0 -22770,0 -22771,0 -22772,0 -22773,0 -22774,0 -22775,0 -22776,0 -22777,0 -22778,0 -22779,0 -22780,0 -22781,0 -22782,0 -22783,0 -22784,0 -22785,0 -22786,0 -22787,0 -22788,0 -22789,0 -22790,0 -22791,0 -22792,0 -22793,0 -22794,0 -22795,0 -22796,0 -22797,0 -22798,0 -22799,0 -22800,0 -22801,0 -22802,0 -22803,0 -22804,0 -22805,0 -22806,0 -22807,0 -22808,0 -22809,0 -22810,0 -22811,0 -22812,0 -22813,0 -22814,0 -22815,0 -22816,0 -22817,0 -22818,0 -22819,0 -22820,0 -22821,0 -22822,0 -22823,0 -22824,0 -22825,0 -22826,0 -22827,0 -22828,0 -22829,0 -22830,0 -22831,0 -22832,0 -22833,0 -22834,0 -22835,0 -22836,0 -22837,0 -22838,0 -22839,0 -22840,0 -22841,0 -22842,0 -22843,0 -22844,0 -22845,0 -22846,0 -22847,0 -22848,0 -22849,0 -22850,0 -22851,0 -22852,0 -22853,0 -22854,0 -22855,0 -22856,0 -22857,0 -22858,0 -22859,0 -22860,0 -22861,0 -22862,0 -22863,0 -22864,0 -22865,0 -22866,0 -22867,0 -22868,0 -22869,0 -22870,0 -22871,0 -22872,0 -22873,0 -22874,0 -22875,0 -22876,0 -22877,0 -22878,0 -22879,0 -22880,0 -22881,0 -22882,0 -22883,0 -22884,0 -22885,0 -22886,0 -22887,0 -22888,0 -22889,0 -22890,0 -22891,0 -22892,0 -22893,0 -22894,0 -22895,0 -22896,0 -22897,0 -22898,0 -22899,0 -22900,0 -22901,0 -22902,0 -22903,0 -22904,0 -22905,0 -22906,0 -22907,0 -22908,0 -22909,0 -22910,0 -22911,0 -22912,0 -22913,0 -22914,0 -22915,0 -22916,0 -22917,0 -22918,0 -22919,0 -22920,0 -22921,0 -22922,0 -22923,0 -22924,0 -22925,0 -22926,0 -22927,0 -22928,0 -22929,0 -22930,0 -22931,0 -22932,0 -22933,0 -22934,0 -22935,0 -22936,0 -22937,0 -22938,0 -22939,0 -22940,0 -22941,0 -22942,0 -22943,0 -22944,0 -22945,0 -22946,0 -22947,0 -22948,0 -22949,0 -22950,0 -22951,0 -22952,0 -22953,0 -22954,0 -22955,0 -22956,0 -22957,0 -22958,0 -22959,0 -22960,0 -22961,0 -22962,0 -22963,0 -22964,0 -22965,0 -22966,0 -22967,0 -22968,0 -22969,0 -22970,0 -22971,0 -22972,0 -22973,0 -22974,0 -22975,0 -22976,0 -22977,0 -22978,0 -22979,0 -22980,0 -22981,0 -22982,0 -22983,0 -22984,0 -22985,0 -22986,0 -22987,0 -22988,0 -22989,0 -22990,0 -22991,0 -22992,0 -22993,0 -22994,0 -22995,0 -22996,0 -22997,0 -22998,0 -22999,0 -23000,0 -23001,0 -23002,0 -23003,0 -23004,0 -23005,0 -23006,0 -23007,0 -23008,0 -23009,0 -23010,0 -23011,0 -23012,0 -23013,0 -23014,0 -23015,0 -23016,0 -23017,0 -23018,0 -23019,0 -23020,0 -23021,0 -23022,0 -23023,0 -23024,0 -23025,0 -23026,0 -23027,0 -23028,0 -23029,0 -23030,0 -23031,0 -23032,0 -23033,0 -23034,0 -23035,0 -23036,0 -23037,0 -23038,0 -23039,0 -23040,0 -23041,0 -23042,0 -23043,0 -23044,0 -23045,0 -23046,0 -23047,0 -23048,0 -23049,0 -23050,0 -23051,0 -23052,0 -23053,0 -23054,0 -23055,0 -23056,0 -23057,0 -23058,0 -23059,0 -23060,0 -23061,0 -23062,0 -23063,0 -23064,0 -23065,0 -23066,0 -23067,0 -23068,0 -23069,0 -23070,0 -23071,0 -23072,0 -23073,0 -23074,0 -23075,0 -23076,0 -23077,0 -23078,0 -23079,0 -23080,0 -23081,0 -23082,0 -23083,0 -23084,0 -23085,0 -23086,0 -23087,0 -23088,0 -23089,0 -23090,0 -23091,0 -23092,0 -23093,0 -23094,0 -23095,0 -23096,0 -23097,0 -23098,0 -23099,0 -23100,0 -23101,0 -23102,0 -23103,0 -23104,0 -23105,0 -23106,0 -23107,0 -23108,0 -23109,0 -23110,0 -23111,0 -23112,0 -23113,0 -23114,0 -23115,0 -23116,0 -23117,0 -23118,0 -23119,0 -23120,0 -23121,0 -23122,0 -23123,0 -23124,0 -23125,0 -23126,0 -23127,0 -23128,0 -23129,0 -23130,0 -23131,0 -23132,0 -23133,0 -23134,0 -23135,0 -23136,0 -23137,0 -23138,0 -23139,0 -23140,0 -23141,0 -23142,0 -23143,0 -23144,0 -23145,0 -23146,0 -23147,0 -23148,0 -23149,0 -23150,0 -23151,0 -23152,0 -23153,0 -23154,0 -23155,0 -23156,0 -23157,0 -23158,0 -23159,0 -23160,0 -23161,0 -23162,0 -23163,0 -23164,0 -23165,0 -23166,0 -23167,0 -23168,0 -23169,0 -23170,0 -23171,0 -23172,0 -23173,0 -23174,0 -23175,0 -23176,0 -23177,0 -23178,0 -23179,0 -23180,0 -23181,0 -23182,0 -23183,0 -23184,0 -23185,0 -23186,0 -23187,0 -23188,0 -23189,0 -23190,0 -23191,0 -23192,0 -23193,0 -23194,0 -23195,0 -23196,0 -23197,0 -23198,0 -23199,0 -23200,0 -23201,0 -23202,0 -23203,0 -23204,0 -23205,0 -23206,0 -23207,0 -23208,0 -23209,0 -23210,0 -23211,0 -23212,0 -23213,0 -23214,0 -23215,0 -23216,0 -23217,0 -23218,0 -23219,0 -23220,0 -23221,0 -23222,0 -23223,0 -23224,0 -23225,0 -23226,0 -23227,0 -23228,0 -23229,0 -23230,0 -23231,0 -23232,0 -23233,0 -23234,0 -23235,0 -23236,0 -23237,0 -23238,0 -23239,0 -23240,0 -23241,0 -23242,0 -23243,0 -23244,0 -23245,0 -23246,0 -23247,0 -23248,0 -23249,0 -23250,0 -23251,0 -23252,0 -23253,0 -23254,0 -23255,0 -23256,0 -23257,0 -23258,0 -23259,0 -23260,0 -23261,0 -23262,0 -23263,0 -23264,0 -23265,0 -23266,0 -23267,0 -23268,0 -23269,0 -23270,0 -23271,0 -23272,0 -23273,0 -23274,0 -23275,0 -23276,0 -23277,0 -23278,0 -23279,0 -23280,0 -23281,0 -23282,0 -23283,0 -23284,0 -23285,0 -23286,0 -23287,0 -23288,0 -23289,0 -23290,0 -23291,0 -23292,0 -23293,0 -23294,0 -23295,0 -23296,0 -23297,0 -23298,0 -23299,0 -23300,0 -23301,0 -23302,0 -23303,0 -23304,0 -23305,0 -23306,0 -23307,0 -23308,0 -23309,0 -23310,0 -23311,0 -23312,0 -23313,0 -23314,0 -23315,0 -23316,0 -23317,0 -23318,0 -23319,0 -23320,0 -23321,0 -23322,0 -23323,0 -23324,0 -23325,0 -23326,0 -23327,0 -23328,0 -23329,0 -23330,0 -23331,0 -23332,0 -23333,0 -23334,0 -23335,0 -23336,0 -23337,0 -23338,0 -23339,0 -23340,0 -23341,0 -23342,0 -23343,0 -23344,0 -23345,0 -23346,0 -23347,0 -23348,0 -23349,0 -23350,0 -23351,0 -23352,0 -23353,0 -23354,0 -23355,0 -23356,0 -23357,0 -23358,0 -23359,0 -23360,0 -23361,0 -23362,0 -23363,0 -23364,0 -23365,0 -23366,0 -23367,0 -23368,0 -23369,0 -23370,0 -23371,0 -23372,0 -23373,0 -23374,0 -23375,0 -23376,0 -23377,0 -23378,0 -23379,0 -23380,0 -23381,0 -23382,0 -23383,0 -23384,0 -23385,0 -23386,0 -23387,0 -23388,0 -23389,0 -23390,0 -23391,0 -23392,0 -23393,0 -23394,0 -23395,0 -23396,0 -23397,0 -23398,0 -23399,0 -23400,0 -23401,0 -23402,0 -23403,0 -23404,0 -23405,0 -23406,0 -23407,0 -23408,0 -23409,0 -23410,0 -23411,0 -23412,0 -23413,0 -23414,0 -23415,0 -23416,0 -23417,0 -23418,0 -23419,0 -23420,0 -23421,0 -23422,0 -23423,0 -23424,0 -23425,0 -23426,0 -23427,0 -23428,0 -23429,0 -23430,0 -23431,0 -23432,0 -23433,0 -23434,0 -23435,0 -23436,0 -23437,0 -23438,0 -23439,0 -23440,0 -23441,0 -23442,0 -23443,0 -23444,0 -23445,0 -23446,0 -23447,0 -23448,0 -23449,0 -23450,0 -23451,0 -23452,0 -23453,0 -23454,0 -23455,0 -23456,0 -23457,0 -23458,0 -23459,0 -23460,0 -23461,0 -23462,0 -23463,0 -23464,0 -23465,0 -23466,0 -23467,0 -23468,0 -23469,0 -23470,0 -23471,0 -23472,0 -23473,0 -23474,0 -23475,0 -23476,0 -23477,0 -23478,0 -23479,0 -23480,0 -23481,0 -23482,0 -23483,0 -23484,0 -23485,0 -23486,0 -23487,0 -23488,0 -23489,0 -23490,0 -23491,0 -23492,0 -23493,0 -23494,0 -23495,0 -23496,0 -23497,0 -23498,0 -23499,0 -23500,0 -23501,0 -23502,0 -23503,0 -23504,0 -23505,0 -23506,0 -23507,0 -23508,0 -23509,0 -23510,0 -23511,0 -23512,0 -23513,0 -23514,0 -23515,0 -23516,0 -23517,0 -23518,0 -23519,0 -23520,0 -23521,0 -23522,0 -23523,0 -23524,0 -23525,0 -23526,0 -23527,0 -23528,0 -23529,0 -23530,0 -23531,0 -23532,0 -23533,0 -23534,0 -23535,0 -23536,0 -23537,0 -23538,0 -23539,0 -23540,0 -23541,0 -23542,0 -23543,0 -23544,0 -23545,0 -23546,0 -23547,0 -23548,0 -23549,0 -23550,0 -23551,0 -23552,0 -23553,0 -23554,0 -23555,0 -23556,0 -23557,0 -23558,0 -23559,0 -23560,0 -23561,0 -23562,0 -23563,0 -23564,0 -23565,0 -23566,0 -23567,0 -23568,0 -23569,0 -23570,0 -23571,0 -23572,0 -23573,0 -23574,0 -23575,0 -23576,0 -23577,0 -23578,0 -23579,0 -23580,0 -23581,0 -23582,0 -23583,0 -23584,0 -23585,0 -23586,0 -23587,0 -23588,0 -23589,0 -23590,0 -23591,0 -23592,0 -23593,0 -23594,0 -23595,0 -23596,0 -23597,0 -23598,0 -23599,0 -23600,0 -23601,0 -23602,0 -23603,0 -23604,0 -23605,0 -23606,0 -23607,0 -23608,0 -23609,0 -23610,0 -23611,0 -23612,0 -23613,0 -23614,0 -23615,0 -23616,0 -23617,0 -23618,0 -23619,0 -23620,0 -23621,0 -23622,0 -23623,0 -23624,0 -23625,0 -23626,0 -23627,0 -23628,0 -23629,0 -23630,0 -23631,0 -23632,0 -23633,0 -23634,0 -23635,0 -23636,0 -23637,0 -23638,0 -23639,0 -23640,0 -23641,0 -23642,0 -23643,0 -23644,0 -23645,0 -23646,0 -23647,0 -23648,0 -23649,0 -23650,0 -23651,0 -23652,0 -23653,0 -23654,0 -23655,0 -23656,0 -23657,0 -23658,0 -23659,0 -23660,0 -23661,0 -23662,0 -23663,0 -23664,0 -23665,0 -23666,0 -23667,0 -23668,0 -23669,0 -23670,0 -23671,0 -23672,0 -23673,0 -23674,0 -23675,0 -23676,0 -23677,0 -23678,0 -23679,0 -23680,0 -23681,0 -23682,0 -23683,0 -23684,0 -23685,0 -23686,0 -23687,0 -23688,0 -23689,0 -23690,0 -23691,0 -23692,0 -23693,0 -23694,0 -23695,0 -23696,0 -23697,0 -23698,0 -23699,0 -23700,0 -23701,0 -23702,0 -23703,0 -23704,0 -23705,0 -23706,0 -23707,0 -23708,0 -23709,0 -23710,0 -23711,0 -23712,0 -23713,0 -23714,0 -23715,0 -23716,0 -23717,0 -23718,0 -23719,0 -23720,0 -23721,0 -23722,0 -23723,0 -23724,0 -23725,0 -23726,0 -23727,0 -23728,0 -23729,0 -23730,0 -23731,0 -23732,0 -23733,0 -23734,0 -23735,0 -23736,0 -23737,0 -23738,0 -23739,0 -23740,0 -23741,0 -23742,0 -23743,0 -23744,0 -23745,0 -23746,0 -23747,0 -23748,0 -23749,0 -23750,0 -23751,0 -23752,0 -23753,0 -23754,0 -23755,0 -23756,0 -23757,0 -23758,0 -23759,0 -23760,0 -23761,0 -23762,0 -23763,0 -23764,0 -23765,0 -23766,0 -23767,0 -23768,0 -23769,0 -23770,0 -23771,0 -23772,0 -23773,0 -23774,0 -23775,0 -23776,0 -23777,0 -23778,0 -23779,0 -23780,0 -23781,0 -23782,0 -23783,0 -23784,0 -23785,0 -23786,0 -23787,0 -23788,0 -23789,0 -23790,0 -23791,0 -23792,0 -23793,0 -23794,0 -23795,0 -23796,0 -23797,0 -23798,0 -23799,0 -23800,0 -23801,0 -23802,0 -23803,0 -23804,0 -23805,0 -23806,0 -23807,0 -23808,0 -23809,0 -23810,0 -23811,0 -23812,0 -23813,0 -23814,0 -23815,0 -23816,0 -23817,0 -23818,0 -23819,0 -23820,0 -23821,0 -23822,0 -23823,0 -23824,0 -23825,0 -23826,0 -23827,0 -23828,0 -23829,0 -23830,0 -23831,0 -23832,0 -23833,0 -23834,0 -23835,0 -23836,0 -23837,0 -23838,0 -23839,0 -23840,0 -23841,0 -23842,0 -23843,0 -23844,0 -23845,0 -23846,0 -23847,0 -23848,0 -23849,0 -23850,0 -23851,0 -23852,0 -23853,0 -23854,0 -23855,0 -23856,0 -23857,0 -23858,0 -23859,0 -23860,0 -23861,0 -23862,0 -23863,0 -23864,0 -23865,0 -23866,0 -23867,0 -23868,0 -23869,0 -23870,0 -23871,0 -23872,0 -23873,0 -23874,0 -23875,0 -23876,0 -23877,0 -23878,0 -23879,0 -23880,0 -23881,0 -23882,0 -23883,0 -23884,0 -23885,0 -23886,0 -23887,0 -23888,0 -23889,0 -23890,0 -23891,0 -23892,0 -23893,0 -23894,0 -23895,0 -23896,0 -23897,0 -23898,0 -23899,0 -23900,0 -23901,0 -23902,0 -23903,0 -23904,0 -23905,0 -23906,0 -23907,0 -23908,0 -23909,0 -23910,0 -23911,0 -23912,0 -23913,0 -23914,0 -23915,0 -23916,0 -23917,0 -23918,0 -23919,0 -23920,0 -23921,0 -23922,0 -23923,0 -23924,0 -23925,0 -23926,0 -23927,0 -23928,0 -23929,0 -23930,0 -23931,0 -23932,0 -23933,0 -23934,0 -23935,0 -23936,0 -23937,0 -23938,0 -23939,0 -23940,0 -23941,0 -23942,0 -23943,0 -23944,0 -23945,0 -23946,0 -23947,0 -23948,0 -23949,0 -23950,0 -23951,0 -23952,0 -23953,0 -23954,0 -23955,0 -23956,0 -23957,0 -23958,0 -23959,0 -23960,0 -23961,0 -23962,0 -23963,0 -23964,0 -23965,0 -23966,0 -23967,0 -23968,0 -23969,0 -23970,0 -23971,0 -23972,0 -23973,0 -23974,0 -23975,0 -23976,0 -23977,0 -23978,0 -23979,0 -23980,0 -23981,0 -23982,0 -23983,0 -23984,0 -23985,0 -23986,0 -23987,0 -23988,0 -23989,0 -23990,0 -23991,0 -23992,0 -23993,0 -23994,0 -23995,0 -23996,0 -23997,0 -23998,0 -23999,0 -24000,0 -24001,0 -24002,0 -24003,0 -24004,0 -24005,0 -24006,0 -24007,0 -24008,0 -24009,0 -24010,0 -24011,0 -24012,0 -24013,0 -24014,0 -24015,0 -24016,0 -24017,0 -24018,0 -24019,0 -24020,0 -24021,0 -24022,0 -24023,0 -24024,0 -24025,0 -24026,0 -24027,0 -24028,0 -24029,0 -24030,0 -24031,0 -24032,0 -24033,0 -24034,0 -24035,0 -24036,0 -24037,0 -24038,0 -24039,0 -24040,0 -24041,0 -24042,0 -24043,0 -24044,0 -24045,0 -24046,0 -24047,0 -24048,0 -24049,0 -24050,0 -24051,0 -24052,0 -24053,0 -24054,0 -24055,0 -24056,0 -24057,0 -24058,0 -24059,0 -24060,0 -24061,0 -24062,0 -24063,0 -24064,0 -24065,0 -24066,0 -24067,0 -24068,0 -24069,0 -24070,0 -24071,0 -24072,0 -24073,0 -24074,0 -24075,0 -24076,0 -24077,0 -24078,0 -24079,0 -24080,0 -24081,0 -24082,0 -24083,0 -24084,0 -24085,0 -24086,0 -24087,0 -24088,0 -24089,0 -24090,0 -24091,0 -24092,0 -24093,0 -24094,0 -24095,0 -24096,0 -24097,0 -24098,0 -24099,0 -24100,0 -24101,0 -24102,0 -24103,0 -24104,0 -24105,0 -24106,0 -24107,0 -24108,0 -24109,0 -24110,0 -24111,0 -24112,0 -24113,0 -24114,0 -24115,0 -24116,0 -24117,0 -24118,0 -24119,0 -24120,0 -24121,0 -24122,0 -24123,0 -24124,0 -24125,0 -24126,0 -24127,0 -24128,0 -24129,0 -24130,0 -24131,0 -24132,0 -24133,0 -24134,0 -24135,0 -24136,0 -24137,0 -24138,0 -24139,0 -24140,0 -24141,0 -24142,0 -24143,0 -24144,0 -24145,0 -24146,0 -24147,0 -24148,0 -24149,0 -24150,0 -24151,0 -24152,0 -24153,0 -24154,0 -24155,0 -24156,0 -24157,0 -24158,0 -24159,0 -24160,0 -24161,0 -24162,0 -24163,0 -24164,0 -24165,0 -24166,0 -24167,0 -24168,0 -24169,0 -24170,0 -24171,0 -24172,0 -24173,0 -24174,0 -24175,0 -24176,0 -24177,0 -24178,0 -24179,0 -24180,0 -24181,0 -24182,0 -24183,0 -24184,0 -24185,0 -24186,0 -24187,0 -24188,0 -24189,0 -24190,0 -24191,0 -24192,0 -24193,0 -24194,0 -24195,0 -24196,0 -24197,0 -24198,0 -24199,0 -24200,0 -24201,0 -24202,0 -24203,0 -24204,0 -24205,0 -24206,0 -24207,0 -24208,0 -24209,0 -24210,0 -24211,0 -24212,0 -24213,0 -24214,0 -24215,0 -24216,0 -24217,0 -24218,0 -24219,0 -24220,0 -24221,0 -24222,0 -24223,0 -24224,0 -24225,0 -24226,0 -24227,0 -24228,0 -24229,0 -24230,0 -24231,0 -24232,0 -24233,0 -24234,0 -24235,0 -24236,0 -24237,0 -24238,0 -24239,0 -24240,0 -24241,0 -24242,0 -24243,0 -24244,0 -24245,0 -24246,0 -24247,0 -24248,0 -24249,0 -24250,0 -24251,0 -24252,0 -24253,0 -24254,0 -24255,0 -24256,0 -24257,0 -24258,0 -24259,0 -24260,0 -24261,0 -24262,0 -24263,0 -24264,0 -24265,0 -24266,0 -24267,0 -24268,0 -24269,0 -24270,0 -24271,0 -24272,0 -24273,0 -24274,0 -24275,0 -24276,0 -24277,0 -24278,0 -24279,0 -24280,0 -24281,0 -24282,0 -24283,0 -24284,0 -24285,0 -24286,0 -24287,0 -24288,0 -24289,0 -24290,0 -24291,0 -24292,0 -24293,0 -24294,0 -24295,0 -24296,0 -24297,0 -24298,0 -24299,0 -24300,0 -24301,0 -24302,0 -24303,0 -24304,0 -24305,0 -24306,0 -24307,0 -24308,0 -24309,0 -24310,0 -24311,0 -24312,0 -24313,0 -24314,0 -24315,0 -24316,0 -24317,0 -24318,0 -24319,0 -24320,0 -24321,0 -24322,0 -24323,0 -24324,0 -24325,0 -24326,0 -24327,0 -24328,0 -24329,0 -24330,0 -24331,0 -24332,0 -24333,0 -24334,0 -24335,0 -24336,0 -24337,0 -24338,0 -24339,0 -24340,0 -24341,0 -24342,0 -24343,0 -24344,0 -24345,0 -24346,0 -24347,0 -24348,0 -24349,0 -24350,0 -24351,0 -24352,0 -24353,0 -24354,0 -24355,0 -24356,0 -24357,0 -24358,0 -24359,0 -24360,0 -24361,0 -24362,0 -24363,0 -24364,0 -24365,0 -24366,0 -24367,0 -24368,0 -24369,0 -24370,0 -24371,0 -24372,0 -24373,0 -24374,0 -24375,0 -24376,0 -24377,0 -24378,0 -24379,0 -24380,0 -24381,0 -24382,0 -24383,0 -24384,0 -24385,0 -24386,0 -24387,0 -24388,0 -24389,0 -24390,0 -24391,0 -24392,0 -24393,0 -24394,0 -24395,0 -24396,0 -24397,0 -24398,0 -24399,0 -24400,0 -24401,0 -24402,0 -24403,0 -24404,0 -24405,0 -24406,0 -24407,0 -24408,0 -24409,0 -24410,0 -24411,0 -24412,0 -24413,0 -24414,0 -24415,0 -24416,0 -24417,0 -24418,0 -24419,0 -24420,0 -24421,0 -24422,0 -24423,0 -24424,0 -24425,0 -24426,0 -24427,0 -24428,0 -24429,0 -24430,0 -24431,0 -24432,0 -24433,0 -24434,0 -24435,0 -24436,0 -24437,0 -24438,0 -24439,0 -24440,0 -24441,0 -24442,0 -24443,0 -24444,0 -24445,0 -24446,0 -24447,0 -24448,0 -24449,0 -24450,0 -24451,0 -24452,0 -24453,0 -24454,0 -24455,0 -24456,0 -24457,0 -24458,0 -24459,0 -24460,0 -24461,0 -24462,0 -24463,0 -24464,0 -24465,0 -24466,0 -24467,0 -24468,0 -24469,0 -24470,0 -24471,0 -24472,0 -24473,0 -24474,0 -24475,0 -24476,0 -24477,0 -24478,0 -24479,0 -24480,0 -24481,0 -24482,0 -24483,0 -24484,0 -24485,0 -24486,0 -24487,0 -24488,0 -24489,0 -24490,0 -24491,0 -24492,0 -24493,0 -24494,0 -24495,0 -24496,0 -24497,0 -24498,0 -24499,0 -24500,0 -24501,0 -24502,0 -24503,0 -24504,0 -24505,0 -24506,0 -24507,0 -24508,0 -24509,0 -24510,0 -24511,0 -24512,0 -24513,0 -24514,0 -24515,0 -24516,0 -24517,0 -24518,0 -24519,0 -24520,0 -24521,0 -24522,0 -24523,0 -24524,0 -24525,0 -24526,0 -24527,0 -24528,0 -24529,0 -24530,0 -24531,0 -24532,0 -24533,0 -24534,0 -24535,0 -24536,0 -24537,0 -24538,0 -24539,0 -24540,0 -24541,0 -24542,0 -24543,0 -24544,0 -24545,0 -24546,0 -24547,0 -24548,0 -24549,0 -24550,0 -24551,0 -24552,0 -24553,0 -24554,0 -24555,0 -24556,0 -24557,0 -24558,0 -24559,0 -24560,0 -24561,0 -24562,0 -24563,0 -24564,0 -24565,0 -24566,0 -24567,0 -24568,0 -24569,0 -24570,0 -24571,0 -24572,0 -24573,0 -24574,0 -24575,0 -24576,0 -24577,0 -24578,0 -24579,0 -24580,0 -24581,0 -24582,0 -24583,0 -24584,0 -24585,0 -24586,0 -24587,0 -24588,0 -24589,0 -24590,0 -24591,0 -24592,0 -24593,0 -24594,0 -24595,0 -24596,0 -24597,0 -24598,0 -24599,0 -24600,0 -24601,0 -24602,0 -24603,0 -24604,0 -24605,0 -24606,0 -24607,0 -24608,0 -24609,0 -24610,0 -24611,0 -24612,0 -24613,0 -24614,0 -24615,0 -24616,0 -24617,0 -24618,0 -24619,0 -24620,0 -24621,0 -24622,0 -24623,0 -24624,0 -24625,0 -24626,0 -24627,0 -24628,0 -24629,0 -24630,0 -24631,0 -24632,0 -24633,0 -24634,0 -24635,0 -24636,0 -24637,0 -24638,0 -24639,0 -24640,0 -24641,0 -24642,0 -24643,0 -24644,0 -24645,0 -24646,0 -24647,0 -24648,0 -24649,0 -24650,0 -24651,0 -24652,0 -24653,0 -24654,0 -24655,0 -24656,0 -24657,0 -24658,0 -24659,0 -24660,0 -24661,0 -24662,0 -24663,0 -24664,0 -24665,0 -24666,0 -24667,0 -24668,0 -24669,0 -24670,0 -24671,0 -24672,0 -24673,0 -24674,0 -24675,0 -24676,0 -24677,0 -24678,0 -24679,0 -24680,0 -24681,0 -24682,0 -24683,0 -24684,0 -24685,0 -24686,0 -24687,0 -24688,0 -24689,0 -24690,0 -24691,0 -24692,0 -24693,0 -24694,0 -24695,0 -24696,0 -24697,0 -24698,0 -24699,0 -24700,0 -24701,0 -24702,0 -24703,0 -24704,0 -24705,0 -24706,0 -24707,0 -24708,0 -24709,0 -24710,0 -24711,0 -24712,0 -24713,0 -24714,0 -24715,0 -24716,0 -24717,0 -24718,0 -24719,0 -24720,0 -24721,0 -24722,0 -24723,0 -24724,0 -24725,0 -24726,0 -24727,0 -24728,0 -24729,0 -24730,0 -24731,0 -24732,0 -24733,0 -24734,0 -24735,0 -24736,0 -24737,0 -24738,0 -24739,0 -24740,0 -24741,0 -24742,0 -24743,0 -24744,0 -24745,0 -24746,0 -24747,0 -24748,0 -24749,0 -24750,0 -24751,0 -24752,0 -24753,0 -24754,0 -24755,0 -24756,0 -24757,0 -24758,0 -24759,0 -24760,0 -24761,0 -24762,0 -24763,0 -24764,0 -24765,0 -24766,0 -24767,0 -24768,0 -24769,0 -24770,0 -24771,0 -24772,0 -24773,0 -24774,0 -24775,0 -24776,0 -24777,0 -24778,0 -24779,0 -24780,0 -24781,0 -24782,0 -24783,0 -24784,0 -24785,0 -24786,0 -24787,0 -24788,0 -24789,0 -24790,0 -24791,0 -24792,0 -24793,0 -24794,0 -24795,0 -24796,0 -24797,0 -24798,0 -24799,0 -24800,0 -24801,0 -24802,0 -24803,0 -24804,0 -24805,0 -24806,0 -24807,0 -24808,0 -24809,0 -24810,0 -24811,0 -24812,0 -24813,0 -24814,0 -24815,0 -24816,0 -24817,0 -24818,0 -24819,0 -24820,0 -24821,0 -24822,0 -24823,0 -24824,0 -24825,0 -24826,0 -24827,0 -24828,0 -24829,0 -24830,0 -24831,0 -24832,0 -24833,0 -24834,0 -24835,0 -24836,0 -24837,0 -24838,0 -24839,0 -24840,0 -24841,0 -24842,0 -24843,0 -24844,0 -24845,0 -24846,0 -24847,0 -24848,0 -24849,0 -24850,0 -24851,0 -24852,0 -24853,0 -24854,0 -24855,0 -24856,0 -24857,0 -24858,0 -24859,0 -24860,0 -24861,0 -24862,0 -24863,0 -24864,0 -24865,0 -24866,0 -24867,0 -24868,0 -24869,0 -24870,0 -24871,0 -24872,0 -24873,0 -24874,0 -24875,0 -24876,0 -24877,0 -24878,0 -24879,0 -24880,0 -24881,0 -24882,0 -24883,0 -24884,0 -24885,0 -24886,0 -24887,0 -24888,0 -24889,0 -24890,0 -24891,0 -24892,0 -24893,0 -24894,0 -24895,0 -24896,0 -24897,0 -24898,0 -24899,0 -24900,0 -24901,0 -24902,0 -24903,0 -24904,0 -24905,0 -24906,0 -24907,0 -24908,0 -24909,0 -24910,0 -24911,0 -24912,0 -24913,0 -24914,0 -24915,0 -24916,0 -24917,0 -24918,0 -24919,0 -24920,0 -24921,0 -24922,0 -24923,0 -24924,0 -24925,0 -24926,0 -24927,0 -24928,0 -24929,0 -24930,0 -24931,0 -24932,0 -24933,0 -24934,0 -24935,0 -24936,0 -24937,0 -24938,0 -24939,0 -24940,0 -24941,0 -24942,0 -24943,0 -24944,0 -24945,0 -24946,0 -24947,0 -24948,0 -24949,0 -24950,0 -24951,0 -24952,0 -24953,0 -24954,0 -24955,0 -24956,0 -24957,0 -24958,0 -24959,0 -24960,0 -24961,0 -24962,0 -24963,0 -24964,0 -24965,0 -24966,0 -24967,0 -24968,0 -24969,0 -24970,0 -24971,0 -24972,0 -24973,0 -24974,0 -24975,0 -24976,0 -24977,0 -24978,0 -24979,0 -24980,0 -24981,0 -24982,0 -24983,0 -24984,0 -24985,0 -24986,0 -24987,0 -24988,0 -24989,0 -24990,0 -24991,0 -24992,0 -24993,0 -24994,0 -24995,0 -24996,0 -24997,0 -24998,0 -24999,0 -25000,0 -25001,0 -25002,0 -25003,0 -25004,0 -25005,0 -25006,0 -25007,0 -25008,0 -25009,0 -25010,0 -25011,0 -25012,0 -25013,0 -25014,0 -25015,0 -25016,0 -25017,0 -25018,0 -25019,0 -25020,0 -25021,0 -25022,0 -25023,0 -25024,0 -25025,0 -25026,0 -25027,0 -25028,0 -25029,0 -25030,0 -25031,0 -25032,0 -25033,0 -25034,0 -25035,0 -25036,0 -25037,0 -25038,0 -25039,0 -25040,0 -25041,0 -25042,0 -25043,0 -25044,0 -25045,0 -25046,0 -25047,0 -25048,0 -25049,0 -25050,0 -25051,0 -25052,0 -25053,0 -25054,0 -25055,0 -25056,0 -25057,0 -25058,0 -25059,0 -25060,0 -25061,0 -25062,0 -25063,0 -25064,0 -25065,0 -25066,0 -25067,0 -25068,0 -25069,0 -25070,0 -25071,0 -25072,0 -25073,0 -25074,0 -25075,0 -25076,0 -25077,0 -25078,0 -25079,0 -25080,0 -25081,0 -25082,0 -25083,0 -25084,0 -25085,0 -25086,0 -25087,0 -25088,0 -25089,0 -25090,0 -25091,0 -25092,0 -25093,0 -25094,0 -25095,0 -25096,0 -25097,0 -25098,0 -25099,0 -25100,0 -25101,0 -25102,0 -25103,0 -25104,0 -25105,0 -25106,0 -25107,0 -25108,0 -25109,0 -25110,0 -25111,0 -25112,0 -25113,0 -25114,0 -25115,0 -25116,0 -25117,0 -25118,0 -25119,0 -25120,0 -25121,0 -25122,0 -25123,0 -25124,0 -25125,0 -25126,0 -25127,0 -25128,0 -25129,0 -25130,0 -25131,0 -25132,0 -25133,0 -25134,0 -25135,0 -25136,0 -25137,0 -25138,0 -25139,0 -25140,0 -25141,0 -25142,0 -25143,0 -25144,0 -25145,0 -25146,0 -25147,0 -25148,0 -25149,0 -25150,0 -25151,0 -25152,0 -25153,0 -25154,0 -25155,0 -25156,0 -25157,0 -25158,0 -25159,0 -25160,0 -25161,0 -25162,0 -25163,0 -25164,0 -25165,0 -25166,0 -25167,0 -25168,0 -25169,0 -25170,0 -25171,0 -25172,0 -25173,0 -25174,0 -25175,0 -25176,0 -25177,0 -25178,0 -25179,0 -25180,0 -25181,0 -25182,0 -25183,0 -25184,0 -25185,0 -25186,0 -25187,0 -25188,0 -25189,0 -25190,0 -25191,0 -25192,0 -25193,0 -25194,0 -25195,0 -25196,0 -25197,0 -25198,0 -25199,0 -25200,0 -25201,0 -25202,0 -25203,0 -25204,0 -25205,0 -25206,0 -25207,0 -25208,0 -25209,0 -25210,0 -25211,0 -25212,0 -25213,0 -25214,0 -25215,0 -25216,0 -25217,0 -25218,0 -25219,0 -25220,0 -25221,0 -25222,0 -25223,0 -25224,0 -25225,0 -25226,0 -25227,0 -25228,0 -25229,0 -25230,0 -25231,0 -25232,0 -25233,0 -25234,0 -25235,0 -25236,0 -25237,0 -25238,0 -25239,0 -25240,0 -25241,0 -25242,0 -25243,0 -25244,0 -25245,0 -25246,0 -25247,0 -25248,0 -25249,0 -25250,0 -25251,0 -25252,0 -25253,0 -25254,0 -25255,0 -25256,0 -25257,0 -25258,0 -25259,0 -25260,0 -25261,0 -25262,0 -25263,0 -25264,0 -25265,0 -25266,0 -25267,0 -25268,0 -25269,0 -25270,0 -25271,0 -25272,0 -25273,0 -25274,0 -25275,0 -25276,0 -25277,0 -25278,0 -25279,0 -25280,0 -25281,0 -25282,0 -25283,0 -25284,0 -25285,0 -25286,0 -25287,0 -25288,0 -25289,0 -25290,0 -25291,0 -25292,0 -25293,0 -25294,0 -25295,0 -25296,0 -25297,0 -25298,0 -25299,0 -25300,0 -25301,0 -25302,0 -25303,0 -25304,0 -25305,0 -25306,0 -25307,0 -25308,0 -25309,0 -25310,0 -25311,0 -25312,0 -25313,0 -25314,0 -25315,0 -25316,0 -25317,0 -25318,0 -25319,0 -25320,0 -25321,0 -25322,0 -25323,0 -25324,0 -25325,0 -25326,0 -25327,0 -25328,0 -25329,0 -25330,0 -25331,0 -25332,0 -25333,0 -25334,0 -25335,0 -25336,0 -25337,0 -25338,0 -25339,0 -25340,0 -25341,0 -25342,0 -25343,0 -25344,0 -25345,0 -25346,0 -25347,0 -25348,0 -25349,0 -25350,0 -25351,0 -25352,0 -25353,0 -25354,0 -25355,0 -25356,0 -25357,0 -25358,0 -25359,0 -25360,0 -25361,0 -25362,0 -25363,0 -25364,0 -25365,0 -25366,0 -25367,0 -25368,0 -25369,0 -25370,0 -25371,0 -25372,0 -25373,0 -25374,0 -25375,0 -25376,0 -25377,0 -25378,0 -25379,0 -25380,0 -25381,0 -25382,0 -25383,0 -25384,0 -25385,0 -25386,0 -25387,0 -25388,0 -25389,0 -25390,0 -25391,0 -25392,0 -25393,0 -25394,0 -25395,0 -25396,0 -25397,0 -25398,0 -25399,0 -25400,0 -25401,0 -25402,0 -25403,0 -25404,0 -25405,0 -25406,0 -25407,0 -25408,0 -25409,0 -25410,0 -25411,0 -25412,0 -25413,0 -25414,0 -25415,0 -25416,0 -25417,0 -25418,0 -25419,0 -25420,0 -25421,0 -25422,0 -25423,0 -25424,0 -25425,0 -25426,0 -25427,0 -25428,0 -25429,0 -25430,0 -25431,0 -25432,0 -25433,0 -25434,0 -25435,0 -25436,0 -25437,0 -25438,0 -25439,0 -25440,0 -25441,0 -25442,0 -25443,0 -25444,0 -25445,0 -25446,0 -25447,0 -25448,0 -25449,0 -25450,0 -25451,0 -25452,0 -25453,0 -25454,0 -25455,0 -25456,0 -25457,0 -25458,0 -25459,0 -25460,0 -25461,0 -25462,0 -25463,0 -25464,0 -25465,0 -25466,0 -25467,0 -25468,0 -25469,0 -25470,0 -25471,0 -25472,0 -25473,0 -25474,0 -25475,0 -25476,0 -25477,0 -25478,0 -25479,0 -25480,0 -25481,0 -25482,0 -25483,0 -25484,0 -25485,0 -25486,0 -25487,0 -25488,0 -25489,0 -25490,0 -25491,0 -25492,0 -25493,0 -25494,0 -25495,0 -25496,0 -25497,0 -25498,0 -25499,0 -25500,0 -25501,0 -25502,0 -25503,0 -25504,0 -25505,0 -25506,0 -25507,0 -25508,0 -25509,0 -25510,0 -25511,0 -25512,0 -25513,0 -25514,0 -25515,0 -25516,0 -25517,0 -25518,0 -25519,0 -25520,0 -25521,0 -25522,0 -25523,0 -25524,0 -25525,0 -25526,0 -25527,0 -25528,0 -25529,0 -25530,0 -25531,0 -25532,0 -25533,0 -25534,0 -25535,0 -25536,0 -25537,0 -25538,0 -25539,0 -25540,0 -25541,0 -25542,0 -25543,0 -25544,0 -25545,0 -25546,0 -25547,0 -25548,0 -25549,0 -25550,0 -25551,0 -25552,0 -25553,0 -25554,0 -25555,0 -25556,0 -25557,0 -25558,0 -25559,0 -25560,0 -25561,0 -25562,0 -25563,0 -25564,0 -25565,0 -25566,0 -25567,0 -25568,0 -25569,0 -25570,0 -25571,0 -25572,0 -25573,0 -25574,0 -25575,0 -25576,0 -25577,0 -25578,0 -25579,0 -25580,0 -25581,0 -25582,0 -25583,0 -25584,0 -25585,0 -25586,0 -25587,0 -25588,0 -25589,0 -25590,0 -25591,0 -25592,0 -25593,0 -25594,0 -25595,0 -25596,0 -25597,0 -25598,0 -25599,0 -25600,0 -25601,0 -25602,0 -25603,0 -25604,0 -25605,0 -25606,0 -25607,0 -25608,0 -25609,0 -25610,0 -25611,0 -25612,0 -25613,0 -25614,0 -25615,0 -25616,0 -25617,0 -25618,0 -25619,0 -25620,0 -25621,0 -25622,0 -25623,0 -25624,0 -25625,0 -25626,0 -25627,0 -25628,0 -25629,0 -25630,0 -25631,0 -25632,0 -25633,0 -25634,0 -25635,0 -25636,0 -25637,0 -25638,0 -25639,0 -25640,0 -25641,0 -25642,0 -25643,0 -25644,0 -25645,0 -25646,0 -25647,0 -25648,0 -25649,0 -25650,0 -25651,0 -25652,0 -25653,0 -25654,0 -25655,0 -25656,0 -25657,0 -25658,0 -25659,0 -25660,0 -25661,0 -25662,0 -25663,0 -25664,0 -25665,0 -25666,0 -25667,0 -25668,0 -25669,0 -25670,0 -25671,0 -25672,0 -25673,0 -25674,0 -25675,0 -25676,0 -25677,0 -25678,0 -25679,0 -25680,0 -25681,0 -25682,0 -25683,0 -25684,0 -25685,0 -25686,0 -25687,0 -25688,0 -25689,0 -25690,0 -25691,0 -25692,0 -25693,0 -25694,0 -25695,0 -25696,0 -25697,0 -25698,0 -25699,0 -25700,0 -25701,0 -25702,0 -25703,0 -25704,0 -25705,0 -25706,0 -25707,0 -25708,0 -25709,0 -25710,0 -25711,0 -25712,0 -25713,0 -25714,0 -25715,0 -25716,0 -25717,0 -25718,0 -25719,0 -25720,0 -25721,0 -25722,0 -25723,0 -25724,0 -25725,0 -25726,0 -25727,0 -25728,0 -25729,0 -25730,0 -25731,0 -25732,0 -25733,0 -25734,0 -25735,0 -25736,0 -25737,0 -25738,0 -25739,0 -25740,0 -25741,0 -25742,0 -25743,0 -25744,0 -25745,0 -25746,0 -25747,0 -25748,0 -25749,0 -25750,0 -25751,0 -25752,0 -25753,0 -25754,0 -25755,0 -25756,0 -25757,0 -25758,0 -25759,0 -25760,0 -25761,0 -25762,0 -25763,0 -25764,0 -25765,0 -25766,0 -25767,0 -25768,0 -25769,0 -25770,0 -25771,0 -25772,0 -25773,0 -25774,0 -25775,0 -25776,0 -25777,0 -25778,0 -25779,0 -25780,0 -25781,0 -25782,0 -25783,0 -25784,0 -25785,0 -25786,0 -25787,0 -25788,0 -25789,0 -25790,0 -25791,0 -25792,0 -25793,0 -25794,0 -25795,0 -25796,0 -25797,0 -25798,0 -25799,0 -25800,0 -25801,0 -25802,0 -25803,0 -25804,0 -25805,0 -25806,0 -25807,0 -25808,0 -25809,0 -25810,0 -25811,0 -25812,0 -25813,0 -25814,0 -25815,0 -25816,0 -25817,0 -25818,0 -25819,0 -25820,0 -25821,0 -25822,0 -25823,0 -25824,0 -25825,0 -25826,0 -25827,0 -25828,0 -25829,0 -25830,0 -25831,0 -25832,0 -25833,0 -25834,0 -25835,0 -25836,0 -25837,0 -25838,0 -25839,0 -25840,0 -25841,0 -25842,0 -25843,0 -25844,0 -25845,0 -25846,0 -25847,0 -25848,0 -25849,0 -25850,0 -25851,0 -25852,0 -25853,0 -25854,0 -25855,0 -25856,0 -25857,0 -25858,0 -25859,0 -25860,0 -25861,0 -25862,0 -25863,0 -25864,0 -25865,0 -25866,0 -25867,0 -25868,0 -25869,0 -25870,0 -25871,0 -25872,0 -25873,0 -25874,0 -25875,0 -25876,0 -25877,0 -25878,0 -25879,0 -25880,0 -25881,0 -25882,0 -25883,0 -25884,0 -25885,0 -25886,0 -25887,0 -25888,0 -25889,0 -25890,0 -25891,0 -25892,0 -25893,0 -25894,0 -25895,0 -25896,0 -25897,0 -25898,0 -25899,0 -25900,0 -25901,0 -25902,0 -25903,0 -25904,0 -25905,0 -25906,0 -25907,0 -25908,0 -25909,0 -25910,0 -25911,0 -25912,0 -25913,0 -25914,0 -25915,0 -25916,0 -25917,0 -25918,0 -25919,0 -25920,0 -25921,0 -25922,0 -25923,0 -25924,0 -25925,0 -25926,0 -25927,0 -25928,0 -25929,0 -25930,0 -25931,0 -25932,0 -25933,0 -25934,0 -25935,0 -25936,0 -25937,0 -25938,0 -25939,0 -25940,0 -25941,0 -25942,0 -25943,0 -25944,0 -25945,0 -25946,0 -25947,0 -25948,0 -25949,0 -25950,0 -25951,0 -25952,0 -25953,0 -25954,0 -25955,0 -25956,0 -25957,0 -25958,0 -25959,0 -25960,0 -25961,0 -25962,0 -25963,0 -25964,0 -25965,0 -25966,0 -25967,0 -25968,0 -25969,0 -25970,0 -25971,0 -25972,0 -25973,0 -25974,0 -25975,0 -25976,0 -25977,0 -25978,0 -25979,0 -25980,0 -25981,0 -25982,0 -25983,0 -25984,0 -25985,0 -25986,0 -25987,0 -25988,0 -25989,0 -25990,0 -25991,0 -25992,0 -25993,0 -25994,0 -25995,0 -25996,0 -25997,0 -25998,0 -25999,0 -26000,0 -26001,0 -26002,0 -26003,0 -26004,0 -26005,0 -26006,0 -26007,0 -26008,0 -26009,0 -26010,0 -26011,0 -26012,0 -26013,0 -26014,0 -26015,0 -26016,0 -26017,0 -26018,0 -26019,0 -26020,0 -26021,0 -26022,0 -26023,0 -26024,0 -26025,0 -26026,0 -26027,0 -26028,0 -26029,0 -26030,0 -26031,0 -26032,0 -26033,0 -26034,0 -26035,0 -26036,0 -26037,0 -26038,0 -26039,0 -26040,0 -26041,0 -26042,0 -26043,0 -26044,0 -26045,0 -26046,0 -26047,0 -26048,0 -26049,0 -26050,0 -26051,0 -26052,0 -26053,0 -26054,0 -26055,0 -26056,0 -26057,0 -26058,0 -26059,0 -26060,0 -26061,0 -26062,0 -26063,0 -26064,0 -26065,0 -26066,0 -26067,0 -26068,0 -26069,0 -26070,0 -26071,0 -26072,0 -26073,0 -26074,0 -26075,0 -26076,0 -26077,0 -26078,0 -26079,0 -26080,0 -26081,0 -26082,0 -26083,0 -26084,0 -26085,0 -26086,0 -26087,0 -26088,0 -26089,0 -26090,0 -26091,0 -26092,0 -26093,0 -26094,0 -26095,0 -26096,0 -26097,0 -26098,0 -26099,0 -26100,0 -26101,0 -26102,0 -26103,0 -26104,0 -26105,0 -26106,0 -26107,0 -26108,0 -26109,0 -26110,0 -26111,0 -26112,0 -26113,0 -26114,0 -26115,0 -26116,0 -26117,0 -26118,0 -26119,0 -26120,0 -26121,0 -26122,0 -26123,0 -26124,0 -26125,0 -26126,0 -26127,0 -26128,0 -26129,0 -26130,0 -26131,0 -26132,0 -26133,0 -26134,0 -26135,0 -26136,0 -26137,0 -26138,0 -26139,0 -26140,0 -26141,0 -26142,0 -26143,0 -26144,0 -26145,0 -26146,0 -26147,0 -26148,0 -26149,0 -26150,0 -26151,0 -26152,0 -26153,0 -26154,0 -26155,0 -26156,0 -26157,0 -26158,0 -26159,0 -26160,0 -26161,0 -26162,0 -26163,0 -26164,0 -26165,0 -26166,0 -26167,0 -26168,0 -26169,0 -26170,0 -26171,0 -26172,0 -26173,0 -26174,0 -26175,0 -26176,0 -26177,0 -26178,0 -26179,0 -26180,0 -26181,0 -26182,0 -26183,0 -26184,0 -26185,0 -26186,0 -26187,0 -26188,0 -26189,0 -26190,0 -26191,0 -26192,0 -26193,0 -26194,0 -26195,0 -26196,0 -26197,0 -26198,0 -26199,0 -26200,0 -26201,0 -26202,0 -26203,0 -26204,0 -26205,0 -26206,0 -26207,0 -26208,0 -26209,0 -26210,0 -26211,0 -26212,0 -26213,0 -26214,0 -26215,0 -26216,0 -26217,0 -26218,0 -26219,0 -26220,0 -26221,0 -26222,0 -26223,0 -26224,0 -26225,0 -26226,0 -26227,0 -26228,0 -26229,0 -26230,0 -26231,0 -26232,0 -26233,0 -26234,0 -26235,0 -26236,0 -26237,0 -26238,0 -26239,0 -26240,0 -26241,0 -26242,0 -26243,0 -26244,0 -26245,0 -26246,0 -26247,0 -26248,0 -26249,0 -26250,0 -26251,0 -26252,0 -26253,0 -26254,0 -26255,0 -26256,0 -26257,0 -26258,0 -26259,0 -26260,0 -26261,0 -26262,0 -26263,0 -26264,0 -26265,0 -26266,0 -26267,0 -26268,0 -26269,0 -26270,0 -26271,0 -26272,0 -26273,0 -26274,0 -26275,0 -26276,0 -26277,0 -26278,0 -26279,0 -26280,0 -26281,0 -26282,0 -26283,0 -26284,0 -26285,0 -26286,0 -26287,0 -26288,0 -26289,0 -26290,0 -26291,0 -26292,0 -26293,0 -26294,0 -26295,0 -26296,0 -26297,0 -26298,0 -26299,0 -26300,0 -26301,0 -26302,0 -26303,0 -26304,0 -26305,0 -26306,0 -26307,0 -26308,0 -26309,0 -26310,0 -26311,0 -26312,0 -26313,0 -26314,0 -26315,0 -26316,0 -26317,0 -26318,0 -26319,0 -26320,0 -26321,0 -26322,0 -26323,0 -26324,0 -26325,0 -26326,0 -26327,0 -26328,0 -26329,0 -26330,0 -26331,0 -26332,0 -26333,0 -26334,0 -26335,0 -26336,0 -26337,0 -26338,0 -26339,0 -26340,0 -26341,0 -26342,0 -26343,0 -26344,0 -26345,0 -26346,0 -26347,0 -26348,0 -26349,0 -26350,0 -26351,0 -26352,0 -26353,0 -26354,0 -26355,0 -26356,0 -26357,0 -26358,0 -26359,0 -26360,0 -26361,0 -26362,0 -26363,0 -26364,0 -26365,0 -26366,0 -26367,0 -26368,0 -26369,0 -26370,0 -26371,0 -26372,0 -26373,0 -26374,0 -26375,0 -26376,0 -26377,0 -26378,0 -26379,0 -26380,0 -26381,0 -26382,0 -26383,0 -26384,0 -26385,0 -26386,0 -26387,0 -26388,0 -26389,0 -26390,0 -26391,0 -26392,0 -26393,0 -26394,0 -26395,0 -26396,0 -26397,0 -26398,0 -26399,0 -26400,0 -26401,0 -26402,0 -26403,0 -26404,0 -26405,0 -26406,0 -26407,0 -26408,0 -26409,0 -26410,0 -26411,0 -26412,0 -26413,0 -26414,0 -26415,0 -26416,0 -26417,0 -26418,0 -26419,0 -26420,0 -26421,0 -26422,0 -26423,0 -26424,0 -26425,0 -26426,0 -26427,0 -26428,0 -26429,0 -26430,0 -26431,0 -26432,0 -26433,0 -26434,0 -26435,0 -26436,0 -26437,0 -26438,0 -26439,0 -26440,0 -26441,0 -26442,0 -26443,0 -26444,0 -26445,0 -26446,0 -26447,0 -26448,0 -26449,0 -26450,0 -26451,0 -26452,0 -26453,0 -26454,0 -26455,0 -26456,0 -26457,0 -26458,0 -26459,0 -26460,0 -26461,0 -26462,0 -26463,0 -26464,0 -26465,0 -26466,0 -26467,0 -26468,0 -26469,0 -26470,0 -26471,0 -26472,0 -26473,0 -26474,0 -26475,0 -26476,0 -26477,0 -26478,0 -26479,0 -26480,0 -26481,0 -26482,0 -26483,0 -26484,0 -26485,0 -26486,0 -26487,0 -26488,0 -26489,0 -26490,0 -26491,0 -26492,0 -26493,0 -26494,0 -26495,0 -26496,0 -26497,0 -26498,0 -26499,0 -26500,0 -26501,0 -26502,0 -26503,0 -26504,0 -26505,0 -26506,0 -26507,0 -26508,0 -26509,0 -26510,0 -26511,0 -26512,0 -26513,0 -26514,0 -26515,0 -26516,0 -26517,0 -26518,0 -26519,0 -26520,0 -26521,0 -26522,0 -26523,0 -26524,0 -26525,0 -26526,0 -26527,0 -26528,0 -26529,0 -26530,0 -26531,0 -26532,0 -26533,0 -26534,0 -26535,0 -26536,0 -26537,0 -26538,0 -26539,0 -26540,0 -26541,0 -26542,0 -26543,0 -26544,0 -26545,0 -26546,0 -26547,0 -26548,0 -26549,0 -26550,0 -26551,0 -26552,0 -26553,0 -26554,0 -26555,0 -26556,0 -26557,0 -26558,0 -26559,0 -26560,0 -26561,0 -26562,0 -26563,0 -26564,0 -26565,0 -26566,0 -26567,0 -26568,0 -26569,0 -26570,0 -26571,0 -26572,0 -26573,0 -26574,0 -26575,0 -26576,0 -26577,0 -26578,0 -26579,0 -26580,0 -26581,0 -26582,0 -26583,0 -26584,0 -26585,0 -26586,0 -26587,0 -26588,0 -26589,0 -26590,0 -26591,0 -26592,0 -26593,0 -26594,0 -26595,0 -26596,0 -26597,0 -26598,0 -26599,0 -26600,0 -26601,0 -26602,0 -26603,0 -26604,0 -26605,0 -26606,0 -26607,0 -26608,0 -26609,0 -26610,0 -26611,0 -26612,0 -26613,0 -26614,0 -26615,0 -26616,0 -26617,0 -26618,0 -26619,0 -26620,0 -26621,0 -26622,0 -26623,0 -26624,0 -26625,0 -26626,0 -26627,0 -26628,0 -26629,0 -26630,0 -26631,0 -26632,0 -26633,0 -26634,0 -26635,0 -26636,0 -26637,0 -26638,0 -26639,0 -26640,0 -26641,0 -26642,0 -26643,0 -26644,0 -26645,0 -26646,0 -26647,0 -26648,0 -26649,0 -26650,0 -26651,0 -26652,0 -26653,0 -26654,0 -26655,0 -26656,0 -26657,0 -26658,0 -26659,0 -26660,0 -26661,0 -26662,0 -26663,0 -26664,0 -26665,0 -26666,0 -26667,0 -26668,0 -26669,0 -26670,0 -26671,0 -26672,0 -26673,0 -26674,0 -26675,0 -26676,0 -26677,0 -26678,0 -26679,0 -26680,0 -26681,0 -26682,0 -26683,0 -26684,0 -26685,0 -26686,0 -26687,0 -26688,0 -26689,0 -26690,0 -26691,0 -26692,0 -26693,0 -26694,0 -26695,0 -26696,0 -26697,0 -26698,0 -26699,0 -26700,0 -26701,0 -26702,0 -26703,0 -26704,0 -26705,0 -26706,0 -26707,0 -26708,0 -26709,0 -26710,0 -26711,0 -26712,0 -26713,0 -26714,0 -26715,0 -26716,0 -26717,0 -26718,0 -26719,0 -26720,0 -26721,0 -26722,0 -26723,0 -26724,0 -26725,0 -26726,0 -26727,0 -26728,0 -26729,0 -26730,0 -26731,0 -26732,0 -26733,0 -26734,0 -26735,0 -26736,0 -26737,0 -26738,0 -26739,0 -26740,0 -26741,0 -26742,0 -26743,0 -26744,0 -26745,0 -26746,0 -26747,0 -26748,0 -26749,0 -26750,0 -26751,0 -26752,0 -26753,0 -26754,0 -26755,0 -26756,0 -26757,0 -26758,0 -26759,0 -26760,0 -26761,0 -26762,0 -26763,0 -26764,0 -26765,0 -26766,0 -26767,0 -26768,0 -26769,0 -26770,0 -26771,0 -26772,0 -26773,0 -26774,0 -26775,0 -26776,0 -26777,0 -26778,0 -26779,0 -26780,0 -26781,0 -26782,0 -26783,0 -26784,0 -26785,0 -26786,0 -26787,0 -26788,0 -26789,0 -26790,0 -26791,0 -26792,0 -26793,0 -26794,0 -26795,0 -26796,0 -26797,0 -26798,0 -26799,0 -26800,0 -26801,0 -26802,0 -26803,0 -26804,0 -26805,0 -26806,0 -26807,0 -26808,0 -26809,0 -26810,0 -26811,0 -26812,0 -26813,0 -26814,0 -26815,0 -26816,0 -26817,0 -26818,0 -26819,0 -26820,0 -26821,0 -26822,0 -26823,0 -26824,0 -26825,0 -26826,0 -26827,0 -26828,0 -26829,0 -26830,0 -26831,0 -26832,0 -26833,0 -26834,0 -26835,0 -26836,0 -26837,0 -26838,0 -26839,0 -26840,0 -26841,0 -26842,0 -26843,0 -26844,0 -26845,0 -26846,0 -26847,0 -26848,0 -26849,0 -26850,0 -26851,0 -26852,0 -26853,0 -26854,0 -26855,0 -26856,0 -26857,0 -26858,0 -26859,0 -26860,0 -26861,0 -26862,0 -26863,0 -26864,0 -26865,0 -26866,0 -26867,0 -26868,0 -26869,0 -26870,0 -26871,0 -26872,0 -26873,0 -26874,0 -26875,0 -26876,0 -26877,0 -26878,0 -26879,0 -26880,0 -26881,0 -26882,0 -26883,0 -26884,0 -26885,0 -26886,0 -26887,0 -26888,0 -26889,0 -26890,0 -26891,0 -26892,0 -26893,0 -26894,0 -26895,0 -26896,0 -26897,0 -26898,0 -26899,0 -26900,0 -26901,0 -26902,0 -26903,0 -26904,0 -26905,0 -26906,0 -26907,0 -26908,0 -26909,0 -26910,0 -26911,0 -26912,0 -26913,0 -26914,0 -26915,0 -26916,0 -26917,0 -26918,0 -26919,0 -26920,0 -26921,0 -26922,0 -26923,0 -26924,0 -26925,0 -26926,0 -26927,0 -26928,0 -26929,0 -26930,0 -26931,0 -26932,0 -26933,0 -26934,0 -26935,0 -26936,0 -26937,0 -26938,0 -26939,0 -26940,0 -26941,0 -26942,0 -26943,0 -26944,0 -26945,0 -26946,0 -26947,0 -26948,0 -26949,0 -26950,0 -26951,0 -26952,0 -26953,0 -26954,0 -26955,0 -26956,0 -26957,0 -26958,0 -26959,0 -26960,0 -26961,0 -26962,0 -26963,0 -26964,0 -26965,0 -26966,0 -26967,0 -26968,0 -26969,0 -26970,0 -26971,0 -26972,0 -26973,0 -26974,0 -26975,0 -26976,0 -26977,0 -26978,0 -26979,0 -26980,0 -26981,0 -26982,0 -26983,0 -26984,0 -26985,0 -26986,0 -26987,0 -26988,0 -26989,0 -26990,0 -26991,0 -26992,0 -26993,0 -26994,0 -26995,0 -26996,0 -26997,0 -26998,0 -26999,0 -27000,0 -27001,0 -27002,0 -27003,0 -27004,0 -27005,0 -27006,0 -27007,0 -27008,0 -27009,0 -27010,0 -27011,0 -27012,0 -27013,0 -27014,0 -27015,0 -27016,0 -27017,0 -27018,0 -27019,0 -27020,0 -27021,0 -27022,0 -27023,0 -27024,0 -27025,0 -27026,0 -27027,0 -27028,0 -27029,0 -27030,0 -27031,0 -27032,0 -27033,0 -27034,0 -27035,0 -27036,0 -27037,0 -27038,0 -27039,0 -27040,0 -27041,0 -27042,0 -27043,0 -27044,0 -27045,0 -27046,0 -27047,0 -27048,0 -27049,0 -27050,0 -27051,0 -27052,0 -27053,0 -27054,0 -27055,0 -27056,0 -27057,0 -27058,0 -27059,0 -27060,0 -27061,0 -27062,0 -27063,0 -27064,0 -27065,0 -27066,0 -27067,0 -27068,0 -27069,0 -27070,0 -27071,0 -27072,0 -27073,0 -27074,0 -27075,0 -27076,0 -27077,0 -27078,0 -27079,0 -27080,0 -27081,0 -27082,0 -27083,0 -27084,0 -27085,0 -27086,0 -27087,0 -27088,0 -27089,0 -27090,0 -27091,0 -27092,0 -27093,0 -27094,0 -27095,0 -27096,0 -27097,0 -27098,0 -27099,0 -27100,0 -27101,0 -27102,0 -27103,0 -27104,0 -27105,0 -27106,0 -27107,0 -27108,0 -27109,0 -27110,0 -27111,0 -27112,0 -27113,0 -27114,0 -27115,0 -27116,0 -27117,0 -27118,0 -27119,0 -27120,0 -27121,0 -27122,0 -27123,0 -27124,0 -27125,0 -27126,0 -27127,0 -27128,0 -27129,0 -27130,0 -27131,0 -27132,0 -27133,0 -27134,0 -27135,0 -27136,0 -27137,0 -27138,0 -27139,0 -27140,0 -27141,0 -27142,0 -27143,0 -27144,0 -27145,0 -27146,0 -27147,0 -27148,0 -27149,0 -27150,0 -27151,0 -27152,0 -27153,0 -27154,0 -27155,0 -27156,0 -27157,0 -27158,0 -27159,0 -27160,0 -27161,0 -27162,0 -27163,0 -27164,0 -27165,0 -27166,0 -27167,0 -27168,0 -27169,0 -27170,0 -27171,0 -27172,0 -27173,0 -27174,0 -27175,0 -27176,0 -27177,0 -27178,0 -27179,0 -27180,0 -27181,0 -27182,0 -27183,0 -27184,0 -27185,0 -27186,0 -27187,0 -27188,0 -27189,0 -27190,0 -27191,0 -27192,0 -27193,0 -27194,0 -27195,0 -27196,0 -27197,0 -27198,0 -27199,0 -27200,0 -27201,0 -27202,0 -27203,0 -27204,0 -27205,0 -27206,0 -27207,0 -27208,0 -27209,0 -27210,0 -27211,0 -27212,0 -27213,0 -27214,0 -27215,0 -27216,0 -27217,0 -27218,0 -27219,0 -27220,0 -27221,0 -27222,0 -27223,0 -27224,0 -27225,0 -27226,0 -27227,0 -27228,0 -27229,0 -27230,0 -27231,0 -27232,0 -27233,0 -27234,0 -27235,0 -27236,0 -27237,0 -27238,0 -27239,0 -27240,0 -27241,0 -27242,0 -27243,0 -27244,0 -27245,0 -27246,0 -27247,0 -27248,0 -27249,0 -27250,0 -27251,0 -27252,0 -27253,0 -27254,0 -27255,0 -27256,0 -27257,0 -27258,0 -27259,0 -27260,0 -27261,0 -27262,0 -27263,0 -27264,0 -27265,0 -27266,0 -27267,0 -27268,0 -27269,0 -27270,0 -27271,0 -27272,0 -27273,0 -27274,0 -27275,0 -27276,0 -27277,0 -27278,0 -27279,0 -27280,0 -27281,0 -27282,0 -27283,0 -27284,0 -27285,0 -27286,0 -27287,0 -27288,0 -27289,0 -27290,0 -27291,0 -27292,0 -27293,0 -27294,0 -27295,0 -27296,0 -27297,0 -27298,0 -27299,0 -27300,0 -27301,0 -27302,0 -27303,0 -27304,0 -27305,0 -27306,0 -27307,0 -27308,0 -27309,0 -27310,0 -27311,0 -27312,0 -27313,0 -27314,0 -27315,0 -27316,0 -27317,0 -27318,0 -27319,0 -27320,0 -27321,0 -27322,0 -27323,0 -27324,0 -27325,0 -27326,0 -27327,0 -27328,0 -27329,0 -27330,0 -27331,0 -27332,0 -27333,0 -27334,0 -27335,0 -27336,0 -27337,0 -27338,0 -27339,0 -27340,0 -27341,0 -27342,0 -27343,0 -27344,0 -27345,0 -27346,0 -27347,0 -27348,0 -27349,0 -27350,0 -27351,0 -27352,0 -27353,0 -27354,0 -27355,0 -27356,0 -27357,0 -27358,0 -27359,0 -27360,0 -27361,0 -27362,0 -27363,0 -27364,0 -27365,0 -27366,0 -27367,0 -27368,0 -27369,0 -27370,0 -27371,0 -27372,0 -27373,0 -27374,0 -27375,0 -27376,0 -27377,0 -27378,0 -27379,0 -27380,0 -27381,0 -27382,0 -27383,0 -27384,0 -27385,0 -27386,0 -27387,0 -27388,0 -27389,0 -27390,0 -27391,0 -27392,0 -27393,0 -27394,0 -27395,0 -27396,0 -27397,0 -27398,0 -27399,0 -27400,0 -27401,0 -27402,0 -27403,0 -27404,0 -27405,0 -27406,0 -27407,0 -27408,0 -27409,0 -27410,0 -27411,0 -27412,0 -27413,0 -27414,0 -27415,0 -27416,0 -27417,0 -27418,0 -27419,0 -27420,0 -27421,0 -27422,0 -27423,0 -27424,0 -27425,0 -27426,0 -27427,0 -27428,0 -27429,0 -27430,0 -27431,0 -27432,0 -27433,0 -27434,0 -27435,0 -27436,0 -27437,0 -27438,0 -27439,0 -27440,0 -27441,0 -27442,0 -27443,0 -27444,0 -27445,0 -27446,0 -27447,0 -27448,0 -27449,0 -27450,0 -27451,0 -27452,0 -27453,0 -27454,0 -27455,0 -27456,0 -27457,0 -27458,0 -27459,0 -27460,0 -27461,0 -27462,0 -27463,0 -27464,0 -27465,0 -27466,0 -27467,0 -27468,0 -27469,0 -27470,0 -27471,0 -27472,0 -27473,0 -27474,0 -27475,0 -27476,0 -27477,0 -27478,0 -27479,0 -27480,0 -27481,0 -27482,0 -27483,0 -27484,0 -27485,0 -27486,0 -27487,0 -27488,0 -27489,0 -27490,0 -27491,0 -27492,0 -27493,0 -27494,0 -27495,0 -27496,0 -27497,0 -27498,0 -27499,0 -27500,0 -27501,0 -27502,0 -27503,0 -27504,0 -27505,0 -27506,0 -27507,0 -27508,0 -27509,0 -27510,0 -27511,0 -27512,0 -27513,0 -27514,0 -27515,0 -27516,0 -27517,0 -27518,0 -27519,0 -27520,0 -27521,0 -27522,0 -27523,0 -27524,0 -27525,0 -27526,0 -27527,0 -27528,0 -27529,0 -27530,0 -27531,0 -27532,0 -27533,0 -27534,0 -27535,0 -27536,0 -27537,0 -27538,0 -27539,0 -27540,0 -27541,0 -27542,0 -27543,0 -27544,0 -27545,0 -27546,0 -27547,0 -27548,0 -27549,0 -27550,0 -27551,0 -27552,0 -27553,0 -27554,0 -27555,0 -27556,0 -27557,0 -27558,0 -27559,0 -27560,0 -27561,0 -27562,0 -27563,0 -27564,0 -27565,0 -27566,0 -27567,0 -27568,0 -27569,0 -27570,0 -27571,0 -27572,0 -27573,0 -27574,0 -27575,0 -27576,0 -27577,0 -27578,0 -27579,0 -27580,0 -27581,0 -27582,0 -27583,0 -27584,0 -27585,0 -27586,0 -27587,0 -27588,0 -27589,0 -27590,0 -27591,0 -27592,0 -27593,0 -27594,0 -27595,0 -27596,0 -27597,0 -27598,0 -27599,0 -27600,0 -27601,0 -27602,0 -27603,0 -27604,0 -27605,0 -27606,0 -27607,0 -27608,0 -27609,0 -27610,0 -27611,0 -27612,0 -27613,0 -27614,0 -27615,0 -27616,0 -27617,0 -27618,0 -27619,0 -27620,0 -27621,0 -27622,0 -27623,0 -27624,0 -27625,0 -27626,0 -27627,0 -27628,0 -27629,0 -27630,0 -27631,0 -27632,0 -27633,0 -27634,0 -27635,0 -27636,0 -27637,0 -27638,0 -27639,0 -27640,0 -27641,0 -27642,0 -27643,0 -27644,0 -27645,0 -27646,0 -27647,0 -27648,0 -27649,0 -27650,0 -27651,0 -27652,0 -27653,0 -27654,0 -27655,0 -27656,0 -27657,0 -27658,0 -27659,0 -27660,0 -27661,0 -27662,0 -27663,0 -27664,0 -27665,0 -27666,0 -27667,0 -27668,0 -27669,0 -27670,0 -27671,0 -27672,0 -27673,0 -27674,0 -27675,0 -27676,0 -27677,0 -27678,0 -27679,0 -27680,0 -27681,0 -27682,0 -27683,0 -27684,0 -27685,0 -27686,0 -27687,0 -27688,0 -27689,0 -27690,0 -27691,0 -27692,0 -27693,0 -27694,0 -27695,0 -27696,0 -27697,0 -27698,0 -27699,0 -27700,0 -27701,0 -27702,0 -27703,0 -27704,0 -27705,0 -27706,0 -27707,0 -27708,0 -27709,0 -27710,0 -27711,0 -27712,0 -27713,0 -27714,0 -27715,0 -27716,0 -27717,0 -27718,0 -27719,0 -27720,0 -27721,0 -27722,0 -27723,0 -27724,0 -27725,0 -27726,0 -27727,0 -27728,0 -27729,0 -27730,0 -27731,0 -27732,0 -27733,0 -27734,0 -27735,0 -27736,0 -27737,0 -27738,0 -27739,0 -27740,0 -27741,0 -27742,0 -27743,0 -27744,0 -27745,0 -27746,0 -27747,0 -27748,0 -27749,0 -27750,0 -27751,0 -27752,0 -27753,0 -27754,0 -27755,0 -27756,0 -27757,0 -27758,0 -27759,0 -27760,0 -27761,0 -27762,0 -27763,0 -27764,0 -27765,0 -27766,0 -27767,0 -27768,0 -27769,0 -27770,0 -27771,0 -27772,0 -27773,0 -27774,0 -27775,0 -27776,0 -27777,0 -27778,0 -27779,0 -27780,0 -27781,0 -27782,0 -27783,0 -27784,0 -27785,0 -27786,0 -27787,0 -27788,0 -27789,0 -27790,0 -27791,0 -27792,0 -27793,0 -27794,0 -27795,0 -27796,0 -27797,0 -27798,0 -27799,0 -27800,0 -27801,0 -27802,0 -27803,0 -27804,0 -27805,0 -27806,0 -27807,0 -27808,0 -27809,0 -27810,0 -27811,0 -27812,0 -27813,0 -27814,0 -27815,0 -27816,0 -27817,0 -27818,0 -27819,0 -27820,0 -27821,0 -27822,0 -27823,0 -27824,0 -27825,0 -27826,0 -27827,0 -27828,0 -27829,0 -27830,0 -27831,0 -27832,0 -27833,0 -27834,0 -27835,0 -27836,0 -27837,0 -27838,0 -27839,0 -27840,0 -27841,0 -27842,0 -27843,0 -27844,0 -27845,0 -27846,0 -27847,0 -27848,0 -27849,0 -27850,0 -27851,0 -27852,0 -27853,0 -27854,0 -27855,0 -27856,0 -27857,0 -27858,0 -27859,0 -27860,0 -27861,0 -27862,0 -27863,0 -27864,0 -27865,0 -27866,0 -27867,0 -27868,0 -27869,0 -27870,0 -27871,0 -27872,0 -27873,0 -27874,0 -27875,0 -27876,0 -27877,0 -27878,0 -27879,0 -27880,0 -27881,0 -27882,0 -27883,0 -27884,0 -27885,0 -27886,0 -27887,0 -27888,0 -27889,0 -27890,0 -27891,0 -27892,0 -27893,0 -27894,0 -27895,0 -27896,0 -27897,0 -27898,0 -27899,0 -27900,0 -27901,0 -27902,0 -27903,0 -27904,0 -27905,0 -27906,0 -27907,0 -27908,0 -27909,0 -27910,0 -27911,0 -27912,0 -27913,0 -27914,0 -27915,0 -27916,0 -27917,0 -27918,0 -27919,0 -27920,0 -27921,0 -27922,0 -27923,0 -27924,0 -27925,0 -27926,0 -27927,0 -27928,0 -27929,0 -27930,0 -27931,0 -27932,0 -27933,0 -27934,0 -27935,0 -27936,0 -27937,0 -27938,0 -27939,0 -27940,0 -27941,0 -27942,0 -27943,0 -27944,0 -27945,0 -27946,0 -27947,0 -27948,0 -27949,0 -27950,0 -27951,0 -27952,0 -27953,0 -27954,0 -27955,0 -27956,0 -27957,0 -27958,0 -27959,0 -27960,0 -27961,0 -27962,0 -27963,0 -27964,0 -27965,0 -27966,0 -27967,0 -27968,0 -27969,0 -27970,0 -27971,0 -27972,0 -27973,0 -27974,0 -27975,0 -27976,0 -27977,0 -27978,0 -27979,0 -27980,0 -27981,0 -27982,0 -27983,0 -27984,0 -27985,0 -27986,0 -27987,0 -27988,0 -27989,0 -27990,0 -27991,0 -27992,0 -27993,0 -27994,0 -27995,0 -27996,0 -27997,0 -27998,0 -27999,0 -28000,0 +ImageId,Label +1,0 +2,0 +3,0 +4,0 +5,0 +6,0 +7,0 +8,0 +9,0 +10,0 +11,0 +12,0 +13,0 +14,0 +15,0 +16,0 +17,0 +18,0 +19,0 +20,0 +21,0 +22,0 +23,0 +24,0 +25,0 +26,0 +27,0 +28,0 +29,0 +30,0 +31,0 +32,0 +33,0 +34,0 +35,0 +36,0 +37,0 +38,0 +39,0 +40,0 +41,0 +42,0 +43,0 +44,0 +45,0 +46,0 +47,0 +48,0 +49,0 +50,0 +51,0 +52,0 +53,0 +54,0 +55,0 +56,0 +57,0 +58,0 +59,0 +60,0 +61,0 +62,0 +63,0 +64,0 +65,0 +66,0 +67,0 +68,0 +69,0 +70,0 +71,0 +72,0 +73,0 +74,0 +75,0 +76,0 +77,0 +78,0 +79,0 +80,0 +81,0 +82,0 +83,0 +84,0 +85,0 +86,0 +87,0 +88,0 +89,0 +90,0 +91,0 +92,0 +93,0 +94,0 +95,0 +96,0 +97,0 +98,0 +99,0 +100,0 +101,0 +102,0 +103,0 +104,0 +105,0 +106,0 +107,0 +108,0 +109,0 +110,0 +111,0 +112,0 +113,0 +114,0 +115,0 +116,0 +117,0 +118,0 +119,0 +120,0 +121,0 +122,0 +123,0 +124,0 +125,0 +126,0 +127,0 +128,0 +129,0 +130,0 +131,0 +132,0 +133,0 +134,0 +135,0 +136,0 +137,0 +138,0 +139,0 +140,0 +141,0 +142,0 +143,0 +144,0 +145,0 +146,0 +147,0 +148,0 +149,0 +150,0 +151,0 +152,0 +153,0 +154,0 +155,0 +156,0 +157,0 +158,0 +159,0 +160,0 +161,0 +162,0 +163,0 +164,0 +165,0 +166,0 +167,0 +168,0 +169,0 +170,0 +171,0 +172,0 +173,0 +174,0 +175,0 +176,0 +177,0 +178,0 +179,0 +180,0 +181,0 +182,0 +183,0 +184,0 +185,0 +186,0 +187,0 +188,0 +189,0 +190,0 +191,0 +192,0 +193,0 +194,0 +195,0 +196,0 +197,0 +198,0 +199,0 +200,0 +201,0 +202,0 +203,0 +204,0 +205,0 +206,0 +207,0 +208,0 +209,0 +210,0 +211,0 +212,0 +213,0 +214,0 +215,0 +216,0 +217,0 +218,0 +219,0 +220,0 +221,0 +222,0 +223,0 +224,0 +225,0 +226,0 +227,0 +228,0 +229,0 +230,0 +231,0 +232,0 +233,0 +234,0 +235,0 +236,0 +237,0 +238,0 +239,0 +240,0 +241,0 +242,0 +243,0 +244,0 +245,0 +246,0 +247,0 +248,0 +249,0 +250,0 +251,0 +252,0 +253,0 +254,0 +255,0 +256,0 +257,0 +258,0 +259,0 +260,0 +261,0 +262,0 +263,0 +264,0 +265,0 +266,0 +267,0 +268,0 +269,0 +270,0 +271,0 +272,0 +273,0 +274,0 +275,0 +276,0 +277,0 +278,0 +279,0 +280,0 +281,0 +282,0 +283,0 +284,0 +285,0 +286,0 +287,0 +288,0 +289,0 +290,0 +291,0 +292,0 +293,0 +294,0 +295,0 +296,0 +297,0 +298,0 +299,0 +300,0 +301,0 +302,0 +303,0 +304,0 +305,0 +306,0 +307,0 +308,0 +309,0 +310,0 +311,0 +312,0 +313,0 +314,0 +315,0 +316,0 +317,0 +318,0 +319,0 +320,0 +321,0 +322,0 +323,0 +324,0 +325,0 +326,0 +327,0 +328,0 +329,0 +330,0 +331,0 +332,0 +333,0 +334,0 +335,0 +336,0 +337,0 +338,0 +339,0 +340,0 +341,0 +342,0 +343,0 +344,0 +345,0 +346,0 +347,0 +348,0 +349,0 +350,0 +351,0 +352,0 +353,0 +354,0 +355,0 +356,0 +357,0 +358,0 +359,0 +360,0 +361,0 +362,0 +363,0 +364,0 +365,0 +366,0 +367,0 +368,0 +369,0 +370,0 +371,0 +372,0 +373,0 +374,0 +375,0 +376,0 +377,0 +378,0 +379,0 +380,0 +381,0 +382,0 +383,0 +384,0 +385,0 +386,0 +387,0 +388,0 +389,0 +390,0 +391,0 +392,0 +393,0 +394,0 +395,0 +396,0 +397,0 +398,0 +399,0 +400,0 +401,0 +402,0 +403,0 +404,0 +405,0 +406,0 +407,0 +408,0 +409,0 +410,0 +411,0 +412,0 +413,0 +414,0 +415,0 +416,0 +417,0 +418,0 +419,0 +420,0 +421,0 +422,0 +423,0 +424,0 +425,0 +426,0 +427,0 +428,0 +429,0 +430,0 +431,0 +432,0 +433,0 +434,0 +435,0 +436,0 +437,0 +438,0 +439,0 +440,0 +441,0 +442,0 +443,0 +444,0 +445,0 +446,0 +447,0 +448,0 +449,0 +450,0 +451,0 +452,0 +453,0 +454,0 +455,0 +456,0 +457,0 +458,0 +459,0 +460,0 +461,0 +462,0 +463,0 +464,0 +465,0 +466,0 +467,0 +468,0 +469,0 +470,0 +471,0 +472,0 +473,0 +474,0 +475,0 +476,0 +477,0 +478,0 +479,0 +480,0 +481,0 +482,0 +483,0 +484,0 +485,0 +486,0 +487,0 +488,0 +489,0 +490,0 +491,0 +492,0 +493,0 +494,0 +495,0 +496,0 +497,0 +498,0 +499,0 +500,0 +501,0 +502,0 +503,0 +504,0 +505,0 +506,0 +507,0 +508,0 +509,0 +510,0 +511,0 +512,0 +513,0 +514,0 +515,0 +516,0 +517,0 +518,0 +519,0 +520,0 +521,0 +522,0 +523,0 +524,0 +525,0 +526,0 +527,0 +528,0 +529,0 +530,0 +531,0 +532,0 +533,0 +534,0 +535,0 +536,0 +537,0 +538,0 +539,0 +540,0 +541,0 +542,0 +543,0 +544,0 +545,0 +546,0 +547,0 +548,0 +549,0 +550,0 +551,0 +552,0 +553,0 +554,0 +555,0 +556,0 +557,0 +558,0 +559,0 +560,0 +561,0 +562,0 +563,0 +564,0 +565,0 +566,0 +567,0 +568,0 +569,0 +570,0 +571,0 +572,0 +573,0 +574,0 +575,0 +576,0 +577,0 +578,0 +579,0 +580,0 +581,0 +582,0 +583,0 +584,0 +585,0 +586,0 +587,0 +588,0 +589,0 +590,0 +591,0 +592,0 +593,0 +594,0 +595,0 +596,0 +597,0 +598,0 +599,0 +600,0 +601,0 +602,0 +603,0 +604,0 +605,0 +606,0 +607,0 +608,0 +609,0 +610,0 +611,0 +612,0 +613,0 +614,0 +615,0 +616,0 +617,0 +618,0 +619,0 +620,0 +621,0 +622,0 +623,0 +624,0 +625,0 +626,0 +627,0 +628,0 +629,0 +630,0 +631,0 +632,0 +633,0 +634,0 +635,0 +636,0 +637,0 +638,0 +639,0 +640,0 +641,0 +642,0 +643,0 +644,0 +645,0 +646,0 +647,0 +648,0 +649,0 +650,0 +651,0 +652,0 +653,0 +654,0 +655,0 +656,0 +657,0 +658,0 +659,0 +660,0 +661,0 +662,0 +663,0 +664,0 +665,0 +666,0 +667,0 +668,0 +669,0 +670,0 +671,0 +672,0 +673,0 +674,0 +675,0 +676,0 +677,0 +678,0 +679,0 +680,0 +681,0 +682,0 +683,0 +684,0 +685,0 +686,0 +687,0 +688,0 +689,0 +690,0 +691,0 +692,0 +693,0 +694,0 +695,0 +696,0 +697,0 +698,0 +699,0 +700,0 +701,0 +702,0 +703,0 +704,0 +705,0 +706,0 +707,0 +708,0 +709,0 +710,0 +711,0 +712,0 +713,0 +714,0 +715,0 +716,0 +717,0 +718,0 +719,0 +720,0 +721,0 +722,0 +723,0 +724,0 +725,0 +726,0 +727,0 +728,0 +729,0 +730,0 +731,0 +732,0 +733,0 +734,0 +735,0 +736,0 +737,0 +738,0 +739,0 +740,0 +741,0 +742,0 +743,0 +744,0 +745,0 +746,0 +747,0 +748,0 +749,0 +750,0 +751,0 +752,0 +753,0 +754,0 +755,0 +756,0 +757,0 +758,0 +759,0 +760,0 +761,0 +762,0 +763,0 +764,0 +765,0 +766,0 +767,0 +768,0 +769,0 +770,0 +771,0 +772,0 +773,0 +774,0 +775,0 +776,0 +777,0 +778,0 +779,0 +780,0 +781,0 +782,0 +783,0 +784,0 +785,0 +786,0 +787,0 +788,0 +789,0 +790,0 +791,0 +792,0 +793,0 +794,0 +795,0 +796,0 +797,0 +798,0 +799,0 +800,0 +801,0 +802,0 +803,0 +804,0 +805,0 +806,0 +807,0 +808,0 +809,0 +810,0 +811,0 +812,0 +813,0 +814,0 +815,0 +816,0 +817,0 +818,0 +819,0 +820,0 +821,0 +822,0 +823,0 +824,0 +825,0 +826,0 +827,0 +828,0 +829,0 +830,0 +831,0 +832,0 +833,0 +834,0 +835,0 +836,0 +837,0 +838,0 +839,0 +840,0 +841,0 +842,0 +843,0 +844,0 +845,0 +846,0 +847,0 +848,0 +849,0 +850,0 +851,0 +852,0 +853,0 +854,0 +855,0 +856,0 +857,0 +858,0 +859,0 +860,0 +861,0 +862,0 +863,0 +864,0 +865,0 +866,0 +867,0 +868,0 +869,0 +870,0 +871,0 +872,0 +873,0 +874,0 +875,0 +876,0 +877,0 +878,0 +879,0 +880,0 +881,0 +882,0 +883,0 +884,0 +885,0 +886,0 +887,0 +888,0 +889,0 +890,0 +891,0 +892,0 +893,0 +894,0 +895,0 +896,0 +897,0 +898,0 +899,0 +900,0 +901,0 +902,0 +903,0 +904,0 +905,0 +906,0 +907,0 +908,0 +909,0 +910,0 +911,0 +912,0 +913,0 +914,0 +915,0 +916,0 +917,0 +918,0 +919,0 +920,0 +921,0 +922,0 +923,0 +924,0 +925,0 +926,0 +927,0 +928,0 +929,0 +930,0 +931,0 +932,0 +933,0 +934,0 +935,0 +936,0 +937,0 +938,0 +939,0 +940,0 +941,0 +942,0 +943,0 +944,0 +945,0 +946,0 +947,0 +948,0 +949,0 +950,0 +951,0 +952,0 +953,0 +954,0 +955,0 +956,0 +957,0 +958,0 +959,0 +960,0 +961,0 +962,0 +963,0 +964,0 +965,0 +966,0 +967,0 +968,0 +969,0 +970,0 +971,0 +972,0 +973,0 +974,0 +975,0 +976,0 +977,0 +978,0 +979,0 +980,0 +981,0 +982,0 +983,0 +984,0 +985,0 +986,0 +987,0 +988,0 +989,0 +990,0 +991,0 +992,0 +993,0 +994,0 +995,0 +996,0 +997,0 +998,0 +999,0 +1000,0 +1001,0 +1002,0 +1003,0 +1004,0 +1005,0 +1006,0 +1007,0 +1008,0 +1009,0 +1010,0 +1011,0 +1012,0 +1013,0 +1014,0 +1015,0 +1016,0 +1017,0 +1018,0 +1019,0 +1020,0 +1021,0 +1022,0 +1023,0 +1024,0 +1025,0 +1026,0 +1027,0 +1028,0 +1029,0 +1030,0 +1031,0 +1032,0 +1033,0 +1034,0 +1035,0 +1036,0 +1037,0 +1038,0 +1039,0 +1040,0 +1041,0 +1042,0 +1043,0 +1044,0 +1045,0 +1046,0 +1047,0 +1048,0 +1049,0 +1050,0 +1051,0 +1052,0 +1053,0 +1054,0 +1055,0 +1056,0 +1057,0 +1058,0 +1059,0 +1060,0 +1061,0 +1062,0 +1063,0 +1064,0 +1065,0 +1066,0 +1067,0 +1068,0 +1069,0 +1070,0 +1071,0 +1072,0 +1073,0 +1074,0 +1075,0 +1076,0 +1077,0 +1078,0 +1079,0 +1080,0 +1081,0 +1082,0 +1083,0 +1084,0 +1085,0 +1086,0 +1087,0 +1088,0 +1089,0 +1090,0 +1091,0 +1092,0 +1093,0 +1094,0 +1095,0 +1096,0 +1097,0 +1098,0 +1099,0 +1100,0 +1101,0 +1102,0 +1103,0 +1104,0 +1105,0 +1106,0 +1107,0 +1108,0 +1109,0 +1110,0 +1111,0 +1112,0 +1113,0 +1114,0 +1115,0 +1116,0 +1117,0 +1118,0 +1119,0 +1120,0 +1121,0 +1122,0 +1123,0 +1124,0 +1125,0 +1126,0 +1127,0 +1128,0 +1129,0 +1130,0 +1131,0 +1132,0 +1133,0 +1134,0 +1135,0 +1136,0 +1137,0 +1138,0 +1139,0 +1140,0 +1141,0 +1142,0 +1143,0 +1144,0 +1145,0 +1146,0 +1147,0 +1148,0 +1149,0 +1150,0 +1151,0 +1152,0 +1153,0 +1154,0 +1155,0 +1156,0 +1157,0 +1158,0 +1159,0 +1160,0 +1161,0 +1162,0 +1163,0 +1164,0 +1165,0 +1166,0 +1167,0 +1168,0 +1169,0 +1170,0 +1171,0 +1172,0 +1173,0 +1174,0 +1175,0 +1176,0 +1177,0 +1178,0 +1179,0 +1180,0 +1181,0 +1182,0 +1183,0 +1184,0 +1185,0 +1186,0 +1187,0 +1188,0 +1189,0 +1190,0 +1191,0 +1192,0 +1193,0 +1194,0 +1195,0 +1196,0 +1197,0 +1198,0 +1199,0 +1200,0 +1201,0 +1202,0 +1203,0 +1204,0 +1205,0 +1206,0 +1207,0 +1208,0 +1209,0 +1210,0 +1211,0 +1212,0 +1213,0 +1214,0 +1215,0 +1216,0 +1217,0 +1218,0 +1219,0 +1220,0 +1221,0 +1222,0 +1223,0 +1224,0 +1225,0 +1226,0 +1227,0 +1228,0 +1229,0 +1230,0 +1231,0 +1232,0 +1233,0 +1234,0 +1235,0 +1236,0 +1237,0 +1238,0 +1239,0 +1240,0 +1241,0 +1242,0 +1243,0 +1244,0 +1245,0 +1246,0 +1247,0 +1248,0 +1249,0 +1250,0 +1251,0 +1252,0 +1253,0 +1254,0 +1255,0 +1256,0 +1257,0 +1258,0 +1259,0 +1260,0 +1261,0 +1262,0 +1263,0 +1264,0 +1265,0 +1266,0 +1267,0 +1268,0 +1269,0 +1270,0 +1271,0 +1272,0 +1273,0 +1274,0 +1275,0 +1276,0 +1277,0 +1278,0 +1279,0 +1280,0 +1281,0 +1282,0 +1283,0 +1284,0 +1285,0 +1286,0 +1287,0 +1288,0 +1289,0 +1290,0 +1291,0 +1292,0 +1293,0 +1294,0 +1295,0 +1296,0 +1297,0 +1298,0 +1299,0 +1300,0 +1301,0 +1302,0 +1303,0 +1304,0 +1305,0 +1306,0 +1307,0 +1308,0 +1309,0 +1310,0 +1311,0 +1312,0 +1313,0 +1314,0 +1315,0 +1316,0 +1317,0 +1318,0 +1319,0 +1320,0 +1321,0 +1322,0 +1323,0 +1324,0 +1325,0 +1326,0 +1327,0 +1328,0 +1329,0 +1330,0 +1331,0 +1332,0 +1333,0 +1334,0 +1335,0 +1336,0 +1337,0 +1338,0 +1339,0 +1340,0 +1341,0 +1342,0 +1343,0 +1344,0 +1345,0 +1346,0 +1347,0 +1348,0 +1349,0 +1350,0 +1351,0 +1352,0 +1353,0 +1354,0 +1355,0 +1356,0 +1357,0 +1358,0 +1359,0 +1360,0 +1361,0 +1362,0 +1363,0 +1364,0 +1365,0 +1366,0 +1367,0 +1368,0 +1369,0 +1370,0 +1371,0 +1372,0 +1373,0 +1374,0 +1375,0 +1376,0 +1377,0 +1378,0 +1379,0 +1380,0 +1381,0 +1382,0 +1383,0 +1384,0 +1385,0 +1386,0 +1387,0 +1388,0 +1389,0 +1390,0 +1391,0 +1392,0 +1393,0 +1394,0 +1395,0 +1396,0 +1397,0 +1398,0 +1399,0 +1400,0 +1401,0 +1402,0 +1403,0 +1404,0 +1405,0 +1406,0 +1407,0 +1408,0 +1409,0 +1410,0 +1411,0 +1412,0 +1413,0 +1414,0 +1415,0 +1416,0 +1417,0 +1418,0 +1419,0 +1420,0 +1421,0 +1422,0 +1423,0 +1424,0 +1425,0 +1426,0 +1427,0 +1428,0 +1429,0 +1430,0 +1431,0 +1432,0 +1433,0 +1434,0 +1435,0 +1436,0 +1437,0 +1438,0 +1439,0 +1440,0 +1441,0 +1442,0 +1443,0 +1444,0 +1445,0 +1446,0 +1447,0 +1448,0 +1449,0 +1450,0 +1451,0 +1452,0 +1453,0 +1454,0 +1455,0 +1456,0 +1457,0 +1458,0 +1459,0 +1460,0 +1461,0 +1462,0 +1463,0 +1464,0 +1465,0 +1466,0 +1467,0 +1468,0 +1469,0 +1470,0 +1471,0 +1472,0 +1473,0 +1474,0 +1475,0 +1476,0 +1477,0 +1478,0 +1479,0 +1480,0 +1481,0 +1482,0 +1483,0 +1484,0 +1485,0 +1486,0 +1487,0 +1488,0 +1489,0 +1490,0 +1491,0 +1492,0 +1493,0 +1494,0 +1495,0 +1496,0 +1497,0 +1498,0 +1499,0 +1500,0 +1501,0 +1502,0 +1503,0 +1504,0 +1505,0 +1506,0 +1507,0 +1508,0 +1509,0 +1510,0 +1511,0 +1512,0 +1513,0 +1514,0 +1515,0 +1516,0 +1517,0 +1518,0 +1519,0 +1520,0 +1521,0 +1522,0 +1523,0 +1524,0 +1525,0 +1526,0 +1527,0 +1528,0 +1529,0 +1530,0 +1531,0 +1532,0 +1533,0 +1534,0 +1535,0 +1536,0 +1537,0 +1538,0 +1539,0 +1540,0 +1541,0 +1542,0 +1543,0 +1544,0 +1545,0 +1546,0 +1547,0 +1548,0 +1549,0 +1550,0 +1551,0 +1552,0 +1553,0 +1554,0 +1555,0 +1556,0 +1557,0 +1558,0 +1559,0 +1560,0 +1561,0 +1562,0 +1563,0 +1564,0 +1565,0 +1566,0 +1567,0 +1568,0 +1569,0 +1570,0 +1571,0 +1572,0 +1573,0 +1574,0 +1575,0 +1576,0 +1577,0 +1578,0 +1579,0 +1580,0 +1581,0 +1582,0 +1583,0 +1584,0 +1585,0 +1586,0 +1587,0 +1588,0 +1589,0 +1590,0 +1591,0 +1592,0 +1593,0 +1594,0 +1595,0 +1596,0 +1597,0 +1598,0 +1599,0 +1600,0 +1601,0 +1602,0 +1603,0 +1604,0 +1605,0 +1606,0 +1607,0 +1608,0 +1609,0 +1610,0 +1611,0 +1612,0 +1613,0 +1614,0 +1615,0 +1616,0 +1617,0 +1618,0 +1619,0 +1620,0 +1621,0 +1622,0 +1623,0 +1624,0 +1625,0 +1626,0 +1627,0 +1628,0 +1629,0 +1630,0 +1631,0 +1632,0 +1633,0 +1634,0 +1635,0 +1636,0 +1637,0 +1638,0 +1639,0 +1640,0 +1641,0 +1642,0 +1643,0 +1644,0 +1645,0 +1646,0 +1647,0 +1648,0 +1649,0 +1650,0 +1651,0 +1652,0 +1653,0 +1654,0 +1655,0 +1656,0 +1657,0 +1658,0 +1659,0 +1660,0 +1661,0 +1662,0 +1663,0 +1664,0 +1665,0 +1666,0 +1667,0 +1668,0 +1669,0 +1670,0 +1671,0 +1672,0 +1673,0 +1674,0 +1675,0 +1676,0 +1677,0 +1678,0 +1679,0 +1680,0 +1681,0 +1682,0 +1683,0 +1684,0 +1685,0 +1686,0 +1687,0 +1688,0 +1689,0 +1690,0 +1691,0 +1692,0 +1693,0 +1694,0 +1695,0 +1696,0 +1697,0 +1698,0 +1699,0 +1700,0 +1701,0 +1702,0 +1703,0 +1704,0 +1705,0 +1706,0 +1707,0 +1708,0 +1709,0 +1710,0 +1711,0 +1712,0 +1713,0 +1714,0 +1715,0 +1716,0 +1717,0 +1718,0 +1719,0 +1720,0 +1721,0 +1722,0 +1723,0 +1724,0 +1725,0 +1726,0 +1727,0 +1728,0 +1729,0 +1730,0 +1731,0 +1732,0 +1733,0 +1734,0 +1735,0 +1736,0 +1737,0 +1738,0 +1739,0 +1740,0 +1741,0 +1742,0 +1743,0 +1744,0 +1745,0 +1746,0 +1747,0 +1748,0 +1749,0 +1750,0 +1751,0 +1752,0 +1753,0 +1754,0 +1755,0 +1756,0 +1757,0 +1758,0 +1759,0 +1760,0 +1761,0 +1762,0 +1763,0 +1764,0 +1765,0 +1766,0 +1767,0 +1768,0 +1769,0 +1770,0 +1771,0 +1772,0 +1773,0 +1774,0 +1775,0 +1776,0 +1777,0 +1778,0 +1779,0 +1780,0 +1781,0 +1782,0 +1783,0 +1784,0 +1785,0 +1786,0 +1787,0 +1788,0 +1789,0 +1790,0 +1791,0 +1792,0 +1793,0 +1794,0 +1795,0 +1796,0 +1797,0 +1798,0 +1799,0 +1800,0 +1801,0 +1802,0 +1803,0 +1804,0 +1805,0 +1806,0 +1807,0 +1808,0 +1809,0 +1810,0 +1811,0 +1812,0 +1813,0 +1814,0 +1815,0 +1816,0 +1817,0 +1818,0 +1819,0 +1820,0 +1821,0 +1822,0 +1823,0 +1824,0 +1825,0 +1826,0 +1827,0 +1828,0 +1829,0 +1830,0 +1831,0 +1832,0 +1833,0 +1834,0 +1835,0 +1836,0 +1837,0 +1838,0 +1839,0 +1840,0 +1841,0 +1842,0 +1843,0 +1844,0 +1845,0 +1846,0 +1847,0 +1848,0 +1849,0 +1850,0 +1851,0 +1852,0 +1853,0 +1854,0 +1855,0 +1856,0 +1857,0 +1858,0 +1859,0 +1860,0 +1861,0 +1862,0 +1863,0 +1864,0 +1865,0 +1866,0 +1867,0 +1868,0 +1869,0 +1870,0 +1871,0 +1872,0 +1873,0 +1874,0 +1875,0 +1876,0 +1877,0 +1878,0 +1879,0 +1880,0 +1881,0 +1882,0 +1883,0 +1884,0 +1885,0 +1886,0 +1887,0 +1888,0 +1889,0 +1890,0 +1891,0 +1892,0 +1893,0 +1894,0 +1895,0 +1896,0 +1897,0 +1898,0 +1899,0 +1900,0 +1901,0 +1902,0 +1903,0 +1904,0 +1905,0 +1906,0 +1907,0 +1908,0 +1909,0 +1910,0 +1911,0 +1912,0 +1913,0 +1914,0 +1915,0 +1916,0 +1917,0 +1918,0 +1919,0 +1920,0 +1921,0 +1922,0 +1923,0 +1924,0 +1925,0 +1926,0 +1927,0 +1928,0 +1929,0 +1930,0 +1931,0 +1932,0 +1933,0 +1934,0 +1935,0 +1936,0 +1937,0 +1938,0 +1939,0 +1940,0 +1941,0 +1942,0 +1943,0 +1944,0 +1945,0 +1946,0 +1947,0 +1948,0 +1949,0 +1950,0 +1951,0 +1952,0 +1953,0 +1954,0 +1955,0 +1956,0 +1957,0 +1958,0 +1959,0 +1960,0 +1961,0 +1962,0 +1963,0 +1964,0 +1965,0 +1966,0 +1967,0 +1968,0 +1969,0 +1970,0 +1971,0 +1972,0 +1973,0 +1974,0 +1975,0 +1976,0 +1977,0 +1978,0 +1979,0 +1980,0 +1981,0 +1982,0 +1983,0 +1984,0 +1985,0 +1986,0 +1987,0 +1988,0 +1989,0 +1990,0 +1991,0 +1992,0 +1993,0 +1994,0 +1995,0 +1996,0 +1997,0 +1998,0 +1999,0 +2000,0 +2001,0 +2002,0 +2003,0 +2004,0 +2005,0 +2006,0 +2007,0 +2008,0 +2009,0 +2010,0 +2011,0 +2012,0 +2013,0 +2014,0 +2015,0 +2016,0 +2017,0 +2018,0 +2019,0 +2020,0 +2021,0 +2022,0 +2023,0 +2024,0 +2025,0 +2026,0 +2027,0 +2028,0 +2029,0 +2030,0 +2031,0 +2032,0 +2033,0 +2034,0 +2035,0 +2036,0 +2037,0 +2038,0 +2039,0 +2040,0 +2041,0 +2042,0 +2043,0 +2044,0 +2045,0 +2046,0 +2047,0 +2048,0 +2049,0 +2050,0 +2051,0 +2052,0 +2053,0 +2054,0 +2055,0 +2056,0 +2057,0 +2058,0 +2059,0 +2060,0 +2061,0 +2062,0 +2063,0 +2064,0 +2065,0 +2066,0 +2067,0 +2068,0 +2069,0 +2070,0 +2071,0 +2072,0 +2073,0 +2074,0 +2075,0 +2076,0 +2077,0 +2078,0 +2079,0 +2080,0 +2081,0 +2082,0 +2083,0 +2084,0 +2085,0 +2086,0 +2087,0 +2088,0 +2089,0 +2090,0 +2091,0 +2092,0 +2093,0 +2094,0 +2095,0 +2096,0 +2097,0 +2098,0 +2099,0 +2100,0 +2101,0 +2102,0 +2103,0 +2104,0 +2105,0 +2106,0 +2107,0 +2108,0 +2109,0 +2110,0 +2111,0 +2112,0 +2113,0 +2114,0 +2115,0 +2116,0 +2117,0 +2118,0 +2119,0 +2120,0 +2121,0 +2122,0 +2123,0 +2124,0 +2125,0 +2126,0 +2127,0 +2128,0 +2129,0 +2130,0 +2131,0 +2132,0 +2133,0 +2134,0 +2135,0 +2136,0 +2137,0 +2138,0 +2139,0 +2140,0 +2141,0 +2142,0 +2143,0 +2144,0 +2145,0 +2146,0 +2147,0 +2148,0 +2149,0 +2150,0 +2151,0 +2152,0 +2153,0 +2154,0 +2155,0 +2156,0 +2157,0 +2158,0 +2159,0 +2160,0 +2161,0 +2162,0 +2163,0 +2164,0 +2165,0 +2166,0 +2167,0 +2168,0 +2169,0 +2170,0 +2171,0 +2172,0 +2173,0 +2174,0 +2175,0 +2176,0 +2177,0 +2178,0 +2179,0 +2180,0 +2181,0 +2182,0 +2183,0 +2184,0 +2185,0 +2186,0 +2187,0 +2188,0 +2189,0 +2190,0 +2191,0 +2192,0 +2193,0 +2194,0 +2195,0 +2196,0 +2197,0 +2198,0 +2199,0 +2200,0 +2201,0 +2202,0 +2203,0 +2204,0 +2205,0 +2206,0 +2207,0 +2208,0 +2209,0 +2210,0 +2211,0 +2212,0 +2213,0 +2214,0 +2215,0 +2216,0 +2217,0 +2218,0 +2219,0 +2220,0 +2221,0 +2222,0 +2223,0 +2224,0 +2225,0 +2226,0 +2227,0 +2228,0 +2229,0 +2230,0 +2231,0 +2232,0 +2233,0 +2234,0 +2235,0 +2236,0 +2237,0 +2238,0 +2239,0 +2240,0 +2241,0 +2242,0 +2243,0 +2244,0 +2245,0 +2246,0 +2247,0 +2248,0 +2249,0 +2250,0 +2251,0 +2252,0 +2253,0 +2254,0 +2255,0 +2256,0 +2257,0 +2258,0 +2259,0 +2260,0 +2261,0 +2262,0 +2263,0 +2264,0 +2265,0 +2266,0 +2267,0 +2268,0 +2269,0 +2270,0 +2271,0 +2272,0 +2273,0 +2274,0 +2275,0 +2276,0 +2277,0 +2278,0 +2279,0 +2280,0 +2281,0 +2282,0 +2283,0 +2284,0 +2285,0 +2286,0 +2287,0 +2288,0 +2289,0 +2290,0 +2291,0 +2292,0 +2293,0 +2294,0 +2295,0 +2296,0 +2297,0 +2298,0 +2299,0 +2300,0 +2301,0 +2302,0 +2303,0 +2304,0 +2305,0 +2306,0 +2307,0 +2308,0 +2309,0 +2310,0 +2311,0 +2312,0 +2313,0 +2314,0 +2315,0 +2316,0 +2317,0 +2318,0 +2319,0 +2320,0 +2321,0 +2322,0 +2323,0 +2324,0 +2325,0 +2326,0 +2327,0 +2328,0 +2329,0 +2330,0 +2331,0 +2332,0 +2333,0 +2334,0 +2335,0 +2336,0 +2337,0 +2338,0 +2339,0 +2340,0 +2341,0 +2342,0 +2343,0 +2344,0 +2345,0 +2346,0 +2347,0 +2348,0 +2349,0 +2350,0 +2351,0 +2352,0 +2353,0 +2354,0 +2355,0 +2356,0 +2357,0 +2358,0 +2359,0 +2360,0 +2361,0 +2362,0 +2363,0 +2364,0 +2365,0 +2366,0 +2367,0 +2368,0 +2369,0 +2370,0 +2371,0 +2372,0 +2373,0 +2374,0 +2375,0 +2376,0 +2377,0 +2378,0 +2379,0 +2380,0 +2381,0 +2382,0 +2383,0 +2384,0 +2385,0 +2386,0 +2387,0 +2388,0 +2389,0 +2390,0 +2391,0 +2392,0 +2393,0 +2394,0 +2395,0 +2396,0 +2397,0 +2398,0 +2399,0 +2400,0 +2401,0 +2402,0 +2403,0 +2404,0 +2405,0 +2406,0 +2407,0 +2408,0 +2409,0 +2410,0 +2411,0 +2412,0 +2413,0 +2414,0 +2415,0 +2416,0 +2417,0 +2418,0 +2419,0 +2420,0 +2421,0 +2422,0 +2423,0 +2424,0 +2425,0 +2426,0 +2427,0 +2428,0 +2429,0 +2430,0 +2431,0 +2432,0 +2433,0 +2434,0 +2435,0 +2436,0 +2437,0 +2438,0 +2439,0 +2440,0 +2441,0 +2442,0 +2443,0 +2444,0 +2445,0 +2446,0 +2447,0 +2448,0 +2449,0 +2450,0 +2451,0 +2452,0 +2453,0 +2454,0 +2455,0 +2456,0 +2457,0 +2458,0 +2459,0 +2460,0 +2461,0 +2462,0 +2463,0 +2464,0 +2465,0 +2466,0 +2467,0 +2468,0 +2469,0 +2470,0 +2471,0 +2472,0 +2473,0 +2474,0 +2475,0 +2476,0 +2477,0 +2478,0 +2479,0 +2480,0 +2481,0 +2482,0 +2483,0 +2484,0 +2485,0 +2486,0 +2487,0 +2488,0 +2489,0 +2490,0 +2491,0 +2492,0 +2493,0 +2494,0 +2495,0 +2496,0 +2497,0 +2498,0 +2499,0 +2500,0 +2501,0 +2502,0 +2503,0 +2504,0 +2505,0 +2506,0 +2507,0 +2508,0 +2509,0 +2510,0 +2511,0 +2512,0 +2513,0 +2514,0 +2515,0 +2516,0 +2517,0 +2518,0 +2519,0 +2520,0 +2521,0 +2522,0 +2523,0 +2524,0 +2525,0 +2526,0 +2527,0 +2528,0 +2529,0 +2530,0 +2531,0 +2532,0 +2533,0 +2534,0 +2535,0 +2536,0 +2537,0 +2538,0 +2539,0 +2540,0 +2541,0 +2542,0 +2543,0 +2544,0 +2545,0 +2546,0 +2547,0 +2548,0 +2549,0 +2550,0 +2551,0 +2552,0 +2553,0 +2554,0 +2555,0 +2556,0 +2557,0 +2558,0 +2559,0 +2560,0 +2561,0 +2562,0 +2563,0 +2564,0 +2565,0 +2566,0 +2567,0 +2568,0 +2569,0 +2570,0 +2571,0 +2572,0 +2573,0 +2574,0 +2575,0 +2576,0 +2577,0 +2578,0 +2579,0 +2580,0 +2581,0 +2582,0 +2583,0 +2584,0 +2585,0 +2586,0 +2587,0 +2588,0 +2589,0 +2590,0 +2591,0 +2592,0 +2593,0 +2594,0 +2595,0 +2596,0 +2597,0 +2598,0 +2599,0 +2600,0 +2601,0 +2602,0 +2603,0 +2604,0 +2605,0 +2606,0 +2607,0 +2608,0 +2609,0 +2610,0 +2611,0 +2612,0 +2613,0 +2614,0 +2615,0 +2616,0 +2617,0 +2618,0 +2619,0 +2620,0 +2621,0 +2622,0 +2623,0 +2624,0 +2625,0 +2626,0 +2627,0 +2628,0 +2629,0 +2630,0 +2631,0 +2632,0 +2633,0 +2634,0 +2635,0 +2636,0 +2637,0 +2638,0 +2639,0 +2640,0 +2641,0 +2642,0 +2643,0 +2644,0 +2645,0 +2646,0 +2647,0 +2648,0 +2649,0 +2650,0 +2651,0 +2652,0 +2653,0 +2654,0 +2655,0 +2656,0 +2657,0 +2658,0 +2659,0 +2660,0 +2661,0 +2662,0 +2663,0 +2664,0 +2665,0 +2666,0 +2667,0 +2668,0 +2669,0 +2670,0 +2671,0 +2672,0 +2673,0 +2674,0 +2675,0 +2676,0 +2677,0 +2678,0 +2679,0 +2680,0 +2681,0 +2682,0 +2683,0 +2684,0 +2685,0 +2686,0 +2687,0 +2688,0 +2689,0 +2690,0 +2691,0 +2692,0 +2693,0 +2694,0 +2695,0 +2696,0 +2697,0 +2698,0 +2699,0 +2700,0 +2701,0 +2702,0 +2703,0 +2704,0 +2705,0 +2706,0 +2707,0 +2708,0 +2709,0 +2710,0 +2711,0 +2712,0 +2713,0 +2714,0 +2715,0 +2716,0 +2717,0 +2718,0 +2719,0 +2720,0 +2721,0 +2722,0 +2723,0 +2724,0 +2725,0 +2726,0 +2727,0 +2728,0 +2729,0 +2730,0 +2731,0 +2732,0 +2733,0 +2734,0 +2735,0 +2736,0 +2737,0 +2738,0 +2739,0 +2740,0 +2741,0 +2742,0 +2743,0 +2744,0 +2745,0 +2746,0 +2747,0 +2748,0 +2749,0 +2750,0 +2751,0 +2752,0 +2753,0 +2754,0 +2755,0 +2756,0 +2757,0 +2758,0 +2759,0 +2760,0 +2761,0 +2762,0 +2763,0 +2764,0 +2765,0 +2766,0 +2767,0 +2768,0 +2769,0 +2770,0 +2771,0 +2772,0 +2773,0 +2774,0 +2775,0 +2776,0 +2777,0 +2778,0 +2779,0 +2780,0 +2781,0 +2782,0 +2783,0 +2784,0 +2785,0 +2786,0 +2787,0 +2788,0 +2789,0 +2790,0 +2791,0 +2792,0 +2793,0 +2794,0 +2795,0 +2796,0 +2797,0 +2798,0 +2799,0 +2800,0 +2801,0 +2802,0 +2803,0 +2804,0 +2805,0 +2806,0 +2807,0 +2808,0 +2809,0 +2810,0 +2811,0 +2812,0 +2813,0 +2814,0 +2815,0 +2816,0 +2817,0 +2818,0 +2819,0 +2820,0 +2821,0 +2822,0 +2823,0 +2824,0 +2825,0 +2826,0 +2827,0 +2828,0 +2829,0 +2830,0 +2831,0 +2832,0 +2833,0 +2834,0 +2835,0 +2836,0 +2837,0 +2838,0 +2839,0 +2840,0 +2841,0 +2842,0 +2843,0 +2844,0 +2845,0 +2846,0 +2847,0 +2848,0 +2849,0 +2850,0 +2851,0 +2852,0 +2853,0 +2854,0 +2855,0 +2856,0 +2857,0 +2858,0 +2859,0 +2860,0 +2861,0 +2862,0 +2863,0 +2864,0 +2865,0 +2866,0 +2867,0 +2868,0 +2869,0 +2870,0 +2871,0 +2872,0 +2873,0 +2874,0 +2875,0 +2876,0 +2877,0 +2878,0 +2879,0 +2880,0 +2881,0 +2882,0 +2883,0 +2884,0 +2885,0 +2886,0 +2887,0 +2888,0 +2889,0 +2890,0 +2891,0 +2892,0 +2893,0 +2894,0 +2895,0 +2896,0 +2897,0 +2898,0 +2899,0 +2900,0 +2901,0 +2902,0 +2903,0 +2904,0 +2905,0 +2906,0 +2907,0 +2908,0 +2909,0 +2910,0 +2911,0 +2912,0 +2913,0 +2914,0 +2915,0 +2916,0 +2917,0 +2918,0 +2919,0 +2920,0 +2921,0 +2922,0 +2923,0 +2924,0 +2925,0 +2926,0 +2927,0 +2928,0 +2929,0 +2930,0 +2931,0 +2932,0 +2933,0 +2934,0 +2935,0 +2936,0 +2937,0 +2938,0 +2939,0 +2940,0 +2941,0 +2942,0 +2943,0 +2944,0 +2945,0 +2946,0 +2947,0 +2948,0 +2949,0 +2950,0 +2951,0 +2952,0 +2953,0 +2954,0 +2955,0 +2956,0 +2957,0 +2958,0 +2959,0 +2960,0 +2961,0 +2962,0 +2963,0 +2964,0 +2965,0 +2966,0 +2967,0 +2968,0 +2969,0 +2970,0 +2971,0 +2972,0 +2973,0 +2974,0 +2975,0 +2976,0 +2977,0 +2978,0 +2979,0 +2980,0 +2981,0 +2982,0 +2983,0 +2984,0 +2985,0 +2986,0 +2987,0 +2988,0 +2989,0 +2990,0 +2991,0 +2992,0 +2993,0 +2994,0 +2995,0 +2996,0 +2997,0 +2998,0 +2999,0 +3000,0 +3001,0 +3002,0 +3003,0 +3004,0 +3005,0 +3006,0 +3007,0 +3008,0 +3009,0 +3010,0 +3011,0 +3012,0 +3013,0 +3014,0 +3015,0 +3016,0 +3017,0 +3018,0 +3019,0 +3020,0 +3021,0 +3022,0 +3023,0 +3024,0 +3025,0 +3026,0 +3027,0 +3028,0 +3029,0 +3030,0 +3031,0 +3032,0 +3033,0 +3034,0 +3035,0 +3036,0 +3037,0 +3038,0 +3039,0 +3040,0 +3041,0 +3042,0 +3043,0 +3044,0 +3045,0 +3046,0 +3047,0 +3048,0 +3049,0 +3050,0 +3051,0 +3052,0 +3053,0 +3054,0 +3055,0 +3056,0 +3057,0 +3058,0 +3059,0 +3060,0 +3061,0 +3062,0 +3063,0 +3064,0 +3065,0 +3066,0 +3067,0 +3068,0 +3069,0 +3070,0 +3071,0 +3072,0 +3073,0 +3074,0 +3075,0 +3076,0 +3077,0 +3078,0 +3079,0 +3080,0 +3081,0 +3082,0 +3083,0 +3084,0 +3085,0 +3086,0 +3087,0 +3088,0 +3089,0 +3090,0 +3091,0 +3092,0 +3093,0 +3094,0 +3095,0 +3096,0 +3097,0 +3098,0 +3099,0 +3100,0 +3101,0 +3102,0 +3103,0 +3104,0 +3105,0 +3106,0 +3107,0 +3108,0 +3109,0 +3110,0 +3111,0 +3112,0 +3113,0 +3114,0 +3115,0 +3116,0 +3117,0 +3118,0 +3119,0 +3120,0 +3121,0 +3122,0 +3123,0 +3124,0 +3125,0 +3126,0 +3127,0 +3128,0 +3129,0 +3130,0 +3131,0 +3132,0 +3133,0 +3134,0 +3135,0 +3136,0 +3137,0 +3138,0 +3139,0 +3140,0 +3141,0 +3142,0 +3143,0 +3144,0 +3145,0 +3146,0 +3147,0 +3148,0 +3149,0 +3150,0 +3151,0 +3152,0 +3153,0 +3154,0 +3155,0 +3156,0 +3157,0 +3158,0 +3159,0 +3160,0 +3161,0 +3162,0 +3163,0 +3164,0 +3165,0 +3166,0 +3167,0 +3168,0 +3169,0 +3170,0 +3171,0 +3172,0 +3173,0 +3174,0 +3175,0 +3176,0 +3177,0 +3178,0 +3179,0 +3180,0 +3181,0 +3182,0 +3183,0 +3184,0 +3185,0 +3186,0 +3187,0 +3188,0 +3189,0 +3190,0 +3191,0 +3192,0 +3193,0 +3194,0 +3195,0 +3196,0 +3197,0 +3198,0 +3199,0 +3200,0 +3201,0 +3202,0 +3203,0 +3204,0 +3205,0 +3206,0 +3207,0 +3208,0 +3209,0 +3210,0 +3211,0 +3212,0 +3213,0 +3214,0 +3215,0 +3216,0 +3217,0 +3218,0 +3219,0 +3220,0 +3221,0 +3222,0 +3223,0 +3224,0 +3225,0 +3226,0 +3227,0 +3228,0 +3229,0 +3230,0 +3231,0 +3232,0 +3233,0 +3234,0 +3235,0 +3236,0 +3237,0 +3238,0 +3239,0 +3240,0 +3241,0 +3242,0 +3243,0 +3244,0 +3245,0 +3246,0 +3247,0 +3248,0 +3249,0 +3250,0 +3251,0 +3252,0 +3253,0 +3254,0 +3255,0 +3256,0 +3257,0 +3258,0 +3259,0 +3260,0 +3261,0 +3262,0 +3263,0 +3264,0 +3265,0 +3266,0 +3267,0 +3268,0 +3269,0 +3270,0 +3271,0 +3272,0 +3273,0 +3274,0 +3275,0 +3276,0 +3277,0 +3278,0 +3279,0 +3280,0 +3281,0 +3282,0 +3283,0 +3284,0 +3285,0 +3286,0 +3287,0 +3288,0 +3289,0 +3290,0 +3291,0 +3292,0 +3293,0 +3294,0 +3295,0 +3296,0 +3297,0 +3298,0 +3299,0 +3300,0 +3301,0 +3302,0 +3303,0 +3304,0 +3305,0 +3306,0 +3307,0 +3308,0 +3309,0 +3310,0 +3311,0 +3312,0 +3313,0 +3314,0 +3315,0 +3316,0 +3317,0 +3318,0 +3319,0 +3320,0 +3321,0 +3322,0 +3323,0 +3324,0 +3325,0 +3326,0 +3327,0 +3328,0 +3329,0 +3330,0 +3331,0 +3332,0 +3333,0 +3334,0 +3335,0 +3336,0 +3337,0 +3338,0 +3339,0 +3340,0 +3341,0 +3342,0 +3343,0 +3344,0 +3345,0 +3346,0 +3347,0 +3348,0 +3349,0 +3350,0 +3351,0 +3352,0 +3353,0 +3354,0 +3355,0 +3356,0 +3357,0 +3358,0 +3359,0 +3360,0 +3361,0 +3362,0 +3363,0 +3364,0 +3365,0 +3366,0 +3367,0 +3368,0 +3369,0 +3370,0 +3371,0 +3372,0 +3373,0 +3374,0 +3375,0 +3376,0 +3377,0 +3378,0 +3379,0 +3380,0 +3381,0 +3382,0 +3383,0 +3384,0 +3385,0 +3386,0 +3387,0 +3388,0 +3389,0 +3390,0 +3391,0 +3392,0 +3393,0 +3394,0 +3395,0 +3396,0 +3397,0 +3398,0 +3399,0 +3400,0 +3401,0 +3402,0 +3403,0 +3404,0 +3405,0 +3406,0 +3407,0 +3408,0 +3409,0 +3410,0 +3411,0 +3412,0 +3413,0 +3414,0 +3415,0 +3416,0 +3417,0 +3418,0 +3419,0 +3420,0 +3421,0 +3422,0 +3423,0 +3424,0 +3425,0 +3426,0 +3427,0 +3428,0 +3429,0 +3430,0 +3431,0 +3432,0 +3433,0 +3434,0 +3435,0 +3436,0 +3437,0 +3438,0 +3439,0 +3440,0 +3441,0 +3442,0 +3443,0 +3444,0 +3445,0 +3446,0 +3447,0 +3448,0 +3449,0 +3450,0 +3451,0 +3452,0 +3453,0 +3454,0 +3455,0 +3456,0 +3457,0 +3458,0 +3459,0 +3460,0 +3461,0 +3462,0 +3463,0 +3464,0 +3465,0 +3466,0 +3467,0 +3468,0 +3469,0 +3470,0 +3471,0 +3472,0 +3473,0 +3474,0 +3475,0 +3476,0 +3477,0 +3478,0 +3479,0 +3480,0 +3481,0 +3482,0 +3483,0 +3484,0 +3485,0 +3486,0 +3487,0 +3488,0 +3489,0 +3490,0 +3491,0 +3492,0 +3493,0 +3494,0 +3495,0 +3496,0 +3497,0 +3498,0 +3499,0 +3500,0 +3501,0 +3502,0 +3503,0 +3504,0 +3505,0 +3506,0 +3507,0 +3508,0 +3509,0 +3510,0 +3511,0 +3512,0 +3513,0 +3514,0 +3515,0 +3516,0 +3517,0 +3518,0 +3519,0 +3520,0 +3521,0 +3522,0 +3523,0 +3524,0 +3525,0 +3526,0 +3527,0 +3528,0 +3529,0 +3530,0 +3531,0 +3532,0 +3533,0 +3534,0 +3535,0 +3536,0 +3537,0 +3538,0 +3539,0 +3540,0 +3541,0 +3542,0 +3543,0 +3544,0 +3545,0 +3546,0 +3547,0 +3548,0 +3549,0 +3550,0 +3551,0 +3552,0 +3553,0 +3554,0 +3555,0 +3556,0 +3557,0 +3558,0 +3559,0 +3560,0 +3561,0 +3562,0 +3563,0 +3564,0 +3565,0 +3566,0 +3567,0 +3568,0 +3569,0 +3570,0 +3571,0 +3572,0 +3573,0 +3574,0 +3575,0 +3576,0 +3577,0 +3578,0 +3579,0 +3580,0 +3581,0 +3582,0 +3583,0 +3584,0 +3585,0 +3586,0 +3587,0 +3588,0 +3589,0 +3590,0 +3591,0 +3592,0 +3593,0 +3594,0 +3595,0 +3596,0 +3597,0 +3598,0 +3599,0 +3600,0 +3601,0 +3602,0 +3603,0 +3604,0 +3605,0 +3606,0 +3607,0 +3608,0 +3609,0 +3610,0 +3611,0 +3612,0 +3613,0 +3614,0 +3615,0 +3616,0 +3617,0 +3618,0 +3619,0 +3620,0 +3621,0 +3622,0 +3623,0 +3624,0 +3625,0 +3626,0 +3627,0 +3628,0 +3629,0 +3630,0 +3631,0 +3632,0 +3633,0 +3634,0 +3635,0 +3636,0 +3637,0 +3638,0 +3639,0 +3640,0 +3641,0 +3642,0 +3643,0 +3644,0 +3645,0 +3646,0 +3647,0 +3648,0 +3649,0 +3650,0 +3651,0 +3652,0 +3653,0 +3654,0 +3655,0 +3656,0 +3657,0 +3658,0 +3659,0 +3660,0 +3661,0 +3662,0 +3663,0 +3664,0 +3665,0 +3666,0 +3667,0 +3668,0 +3669,0 +3670,0 +3671,0 +3672,0 +3673,0 +3674,0 +3675,0 +3676,0 +3677,0 +3678,0 +3679,0 +3680,0 +3681,0 +3682,0 +3683,0 +3684,0 +3685,0 +3686,0 +3687,0 +3688,0 +3689,0 +3690,0 +3691,0 +3692,0 +3693,0 +3694,0 +3695,0 +3696,0 +3697,0 +3698,0 +3699,0 +3700,0 +3701,0 +3702,0 +3703,0 +3704,0 +3705,0 +3706,0 +3707,0 +3708,0 +3709,0 +3710,0 +3711,0 +3712,0 +3713,0 +3714,0 +3715,0 +3716,0 +3717,0 +3718,0 +3719,0 +3720,0 +3721,0 +3722,0 +3723,0 +3724,0 +3725,0 +3726,0 +3727,0 +3728,0 +3729,0 +3730,0 +3731,0 +3732,0 +3733,0 +3734,0 +3735,0 +3736,0 +3737,0 +3738,0 +3739,0 +3740,0 +3741,0 +3742,0 +3743,0 +3744,0 +3745,0 +3746,0 +3747,0 +3748,0 +3749,0 +3750,0 +3751,0 +3752,0 +3753,0 +3754,0 +3755,0 +3756,0 +3757,0 +3758,0 +3759,0 +3760,0 +3761,0 +3762,0 +3763,0 +3764,0 +3765,0 +3766,0 +3767,0 +3768,0 +3769,0 +3770,0 +3771,0 +3772,0 +3773,0 +3774,0 +3775,0 +3776,0 +3777,0 +3778,0 +3779,0 +3780,0 +3781,0 +3782,0 +3783,0 +3784,0 +3785,0 +3786,0 +3787,0 +3788,0 +3789,0 +3790,0 +3791,0 +3792,0 +3793,0 +3794,0 +3795,0 +3796,0 +3797,0 +3798,0 +3799,0 +3800,0 +3801,0 +3802,0 +3803,0 +3804,0 +3805,0 +3806,0 +3807,0 +3808,0 +3809,0 +3810,0 +3811,0 +3812,0 +3813,0 +3814,0 +3815,0 +3816,0 +3817,0 +3818,0 +3819,0 +3820,0 +3821,0 +3822,0 +3823,0 +3824,0 +3825,0 +3826,0 +3827,0 +3828,0 +3829,0 +3830,0 +3831,0 +3832,0 +3833,0 +3834,0 +3835,0 +3836,0 +3837,0 +3838,0 +3839,0 +3840,0 +3841,0 +3842,0 +3843,0 +3844,0 +3845,0 +3846,0 +3847,0 +3848,0 +3849,0 +3850,0 +3851,0 +3852,0 +3853,0 +3854,0 +3855,0 +3856,0 +3857,0 +3858,0 +3859,0 +3860,0 +3861,0 +3862,0 +3863,0 +3864,0 +3865,0 +3866,0 +3867,0 +3868,0 +3869,0 +3870,0 +3871,0 +3872,0 +3873,0 +3874,0 +3875,0 +3876,0 +3877,0 +3878,0 +3879,0 +3880,0 +3881,0 +3882,0 +3883,0 +3884,0 +3885,0 +3886,0 +3887,0 +3888,0 +3889,0 +3890,0 +3891,0 +3892,0 +3893,0 +3894,0 +3895,0 +3896,0 +3897,0 +3898,0 +3899,0 +3900,0 +3901,0 +3902,0 +3903,0 +3904,0 +3905,0 +3906,0 +3907,0 +3908,0 +3909,0 +3910,0 +3911,0 +3912,0 +3913,0 +3914,0 +3915,0 +3916,0 +3917,0 +3918,0 +3919,0 +3920,0 +3921,0 +3922,0 +3923,0 +3924,0 +3925,0 +3926,0 +3927,0 +3928,0 +3929,0 +3930,0 +3931,0 +3932,0 +3933,0 +3934,0 +3935,0 +3936,0 +3937,0 +3938,0 +3939,0 +3940,0 +3941,0 +3942,0 +3943,0 +3944,0 +3945,0 +3946,0 +3947,0 +3948,0 +3949,0 +3950,0 +3951,0 +3952,0 +3953,0 +3954,0 +3955,0 +3956,0 +3957,0 +3958,0 +3959,0 +3960,0 +3961,0 +3962,0 +3963,0 +3964,0 +3965,0 +3966,0 +3967,0 +3968,0 +3969,0 +3970,0 +3971,0 +3972,0 +3973,0 +3974,0 +3975,0 +3976,0 +3977,0 +3978,0 +3979,0 +3980,0 +3981,0 +3982,0 +3983,0 +3984,0 +3985,0 +3986,0 +3987,0 +3988,0 +3989,0 +3990,0 +3991,0 +3992,0 +3993,0 +3994,0 +3995,0 +3996,0 +3997,0 +3998,0 +3999,0 +4000,0 +4001,0 +4002,0 +4003,0 +4004,0 +4005,0 +4006,0 +4007,0 +4008,0 +4009,0 +4010,0 +4011,0 +4012,0 +4013,0 +4014,0 +4015,0 +4016,0 +4017,0 +4018,0 +4019,0 +4020,0 +4021,0 +4022,0 +4023,0 +4024,0 +4025,0 +4026,0 +4027,0 +4028,0 +4029,0 +4030,0 +4031,0 +4032,0 +4033,0 +4034,0 +4035,0 +4036,0 +4037,0 +4038,0 +4039,0 +4040,0 +4041,0 +4042,0 +4043,0 +4044,0 +4045,0 +4046,0 +4047,0 +4048,0 +4049,0 +4050,0 +4051,0 +4052,0 +4053,0 +4054,0 +4055,0 +4056,0 +4057,0 +4058,0 +4059,0 +4060,0 +4061,0 +4062,0 +4063,0 +4064,0 +4065,0 +4066,0 +4067,0 +4068,0 +4069,0 +4070,0 +4071,0 +4072,0 +4073,0 +4074,0 +4075,0 +4076,0 +4077,0 +4078,0 +4079,0 +4080,0 +4081,0 +4082,0 +4083,0 +4084,0 +4085,0 +4086,0 +4087,0 +4088,0 +4089,0 +4090,0 +4091,0 +4092,0 +4093,0 +4094,0 +4095,0 +4096,0 +4097,0 +4098,0 +4099,0 +4100,0 +4101,0 +4102,0 +4103,0 +4104,0 +4105,0 +4106,0 +4107,0 +4108,0 +4109,0 +4110,0 +4111,0 +4112,0 +4113,0 +4114,0 +4115,0 +4116,0 +4117,0 +4118,0 +4119,0 +4120,0 +4121,0 +4122,0 +4123,0 +4124,0 +4125,0 +4126,0 +4127,0 +4128,0 +4129,0 +4130,0 +4131,0 +4132,0 +4133,0 +4134,0 +4135,0 +4136,0 +4137,0 +4138,0 +4139,0 +4140,0 +4141,0 +4142,0 +4143,0 +4144,0 +4145,0 +4146,0 +4147,0 +4148,0 +4149,0 +4150,0 +4151,0 +4152,0 +4153,0 +4154,0 +4155,0 +4156,0 +4157,0 +4158,0 +4159,0 +4160,0 +4161,0 +4162,0 +4163,0 +4164,0 +4165,0 +4166,0 +4167,0 +4168,0 +4169,0 +4170,0 +4171,0 +4172,0 +4173,0 +4174,0 +4175,0 +4176,0 +4177,0 +4178,0 +4179,0 +4180,0 +4181,0 +4182,0 +4183,0 +4184,0 +4185,0 +4186,0 +4187,0 +4188,0 +4189,0 +4190,0 +4191,0 +4192,0 +4193,0 +4194,0 +4195,0 +4196,0 +4197,0 +4198,0 +4199,0 +4200,0 +4201,0 +4202,0 +4203,0 +4204,0 +4205,0 +4206,0 +4207,0 +4208,0 +4209,0 +4210,0 +4211,0 +4212,0 +4213,0 +4214,0 +4215,0 +4216,0 +4217,0 +4218,0 +4219,0 +4220,0 +4221,0 +4222,0 +4223,0 +4224,0 +4225,0 +4226,0 +4227,0 +4228,0 +4229,0 +4230,0 +4231,0 +4232,0 +4233,0 +4234,0 +4235,0 +4236,0 +4237,0 +4238,0 +4239,0 +4240,0 +4241,0 +4242,0 +4243,0 +4244,0 +4245,0 +4246,0 +4247,0 +4248,0 +4249,0 +4250,0 +4251,0 +4252,0 +4253,0 +4254,0 +4255,0 +4256,0 +4257,0 +4258,0 +4259,0 +4260,0 +4261,0 +4262,0 +4263,0 +4264,0 +4265,0 +4266,0 +4267,0 +4268,0 +4269,0 +4270,0 +4271,0 +4272,0 +4273,0 +4274,0 +4275,0 +4276,0 +4277,0 +4278,0 +4279,0 +4280,0 +4281,0 +4282,0 +4283,0 +4284,0 +4285,0 +4286,0 +4287,0 +4288,0 +4289,0 +4290,0 +4291,0 +4292,0 +4293,0 +4294,0 +4295,0 +4296,0 +4297,0 +4298,0 +4299,0 +4300,0 +4301,0 +4302,0 +4303,0 +4304,0 +4305,0 +4306,0 +4307,0 +4308,0 +4309,0 +4310,0 +4311,0 +4312,0 +4313,0 +4314,0 +4315,0 +4316,0 +4317,0 +4318,0 +4319,0 +4320,0 +4321,0 +4322,0 +4323,0 +4324,0 +4325,0 +4326,0 +4327,0 +4328,0 +4329,0 +4330,0 +4331,0 +4332,0 +4333,0 +4334,0 +4335,0 +4336,0 +4337,0 +4338,0 +4339,0 +4340,0 +4341,0 +4342,0 +4343,0 +4344,0 +4345,0 +4346,0 +4347,0 +4348,0 +4349,0 +4350,0 +4351,0 +4352,0 +4353,0 +4354,0 +4355,0 +4356,0 +4357,0 +4358,0 +4359,0 +4360,0 +4361,0 +4362,0 +4363,0 +4364,0 +4365,0 +4366,0 +4367,0 +4368,0 +4369,0 +4370,0 +4371,0 +4372,0 +4373,0 +4374,0 +4375,0 +4376,0 +4377,0 +4378,0 +4379,0 +4380,0 +4381,0 +4382,0 +4383,0 +4384,0 +4385,0 +4386,0 +4387,0 +4388,0 +4389,0 +4390,0 +4391,0 +4392,0 +4393,0 +4394,0 +4395,0 +4396,0 +4397,0 +4398,0 +4399,0 +4400,0 +4401,0 +4402,0 +4403,0 +4404,0 +4405,0 +4406,0 +4407,0 +4408,0 +4409,0 +4410,0 +4411,0 +4412,0 +4413,0 +4414,0 +4415,0 +4416,0 +4417,0 +4418,0 +4419,0 +4420,0 +4421,0 +4422,0 +4423,0 +4424,0 +4425,0 +4426,0 +4427,0 +4428,0 +4429,0 +4430,0 +4431,0 +4432,0 +4433,0 +4434,0 +4435,0 +4436,0 +4437,0 +4438,0 +4439,0 +4440,0 +4441,0 +4442,0 +4443,0 +4444,0 +4445,0 +4446,0 +4447,0 +4448,0 +4449,0 +4450,0 +4451,0 +4452,0 +4453,0 +4454,0 +4455,0 +4456,0 +4457,0 +4458,0 +4459,0 +4460,0 +4461,0 +4462,0 +4463,0 +4464,0 +4465,0 +4466,0 +4467,0 +4468,0 +4469,0 +4470,0 +4471,0 +4472,0 +4473,0 +4474,0 +4475,0 +4476,0 +4477,0 +4478,0 +4479,0 +4480,0 +4481,0 +4482,0 +4483,0 +4484,0 +4485,0 +4486,0 +4487,0 +4488,0 +4489,0 +4490,0 +4491,0 +4492,0 +4493,0 +4494,0 +4495,0 +4496,0 +4497,0 +4498,0 +4499,0 +4500,0 +4501,0 +4502,0 +4503,0 +4504,0 +4505,0 +4506,0 +4507,0 +4508,0 +4509,0 +4510,0 +4511,0 +4512,0 +4513,0 +4514,0 +4515,0 +4516,0 +4517,0 +4518,0 +4519,0 +4520,0 +4521,0 +4522,0 +4523,0 +4524,0 +4525,0 +4526,0 +4527,0 +4528,0 +4529,0 +4530,0 +4531,0 +4532,0 +4533,0 +4534,0 +4535,0 +4536,0 +4537,0 +4538,0 +4539,0 +4540,0 +4541,0 +4542,0 +4543,0 +4544,0 +4545,0 +4546,0 +4547,0 +4548,0 +4549,0 +4550,0 +4551,0 +4552,0 +4553,0 +4554,0 +4555,0 +4556,0 +4557,0 +4558,0 +4559,0 +4560,0 +4561,0 +4562,0 +4563,0 +4564,0 +4565,0 +4566,0 +4567,0 +4568,0 +4569,0 +4570,0 +4571,0 +4572,0 +4573,0 +4574,0 +4575,0 +4576,0 +4577,0 +4578,0 +4579,0 +4580,0 +4581,0 +4582,0 +4583,0 +4584,0 +4585,0 +4586,0 +4587,0 +4588,0 +4589,0 +4590,0 +4591,0 +4592,0 +4593,0 +4594,0 +4595,0 +4596,0 +4597,0 +4598,0 +4599,0 +4600,0 +4601,0 +4602,0 +4603,0 +4604,0 +4605,0 +4606,0 +4607,0 +4608,0 +4609,0 +4610,0 +4611,0 +4612,0 +4613,0 +4614,0 +4615,0 +4616,0 +4617,0 +4618,0 +4619,0 +4620,0 +4621,0 +4622,0 +4623,0 +4624,0 +4625,0 +4626,0 +4627,0 +4628,0 +4629,0 +4630,0 +4631,0 +4632,0 +4633,0 +4634,0 +4635,0 +4636,0 +4637,0 +4638,0 +4639,0 +4640,0 +4641,0 +4642,0 +4643,0 +4644,0 +4645,0 +4646,0 +4647,0 +4648,0 +4649,0 +4650,0 +4651,0 +4652,0 +4653,0 +4654,0 +4655,0 +4656,0 +4657,0 +4658,0 +4659,0 +4660,0 +4661,0 +4662,0 +4663,0 +4664,0 +4665,0 +4666,0 +4667,0 +4668,0 +4669,0 +4670,0 +4671,0 +4672,0 +4673,0 +4674,0 +4675,0 +4676,0 +4677,0 +4678,0 +4679,0 +4680,0 +4681,0 +4682,0 +4683,0 +4684,0 +4685,0 +4686,0 +4687,0 +4688,0 +4689,0 +4690,0 +4691,0 +4692,0 +4693,0 +4694,0 +4695,0 +4696,0 +4697,0 +4698,0 +4699,0 +4700,0 +4701,0 +4702,0 +4703,0 +4704,0 +4705,0 +4706,0 +4707,0 +4708,0 +4709,0 +4710,0 +4711,0 +4712,0 +4713,0 +4714,0 +4715,0 +4716,0 +4717,0 +4718,0 +4719,0 +4720,0 +4721,0 +4722,0 +4723,0 +4724,0 +4725,0 +4726,0 +4727,0 +4728,0 +4729,0 +4730,0 +4731,0 +4732,0 +4733,0 +4734,0 +4735,0 +4736,0 +4737,0 +4738,0 +4739,0 +4740,0 +4741,0 +4742,0 +4743,0 +4744,0 +4745,0 +4746,0 +4747,0 +4748,0 +4749,0 +4750,0 +4751,0 +4752,0 +4753,0 +4754,0 +4755,0 +4756,0 +4757,0 +4758,0 +4759,0 +4760,0 +4761,0 +4762,0 +4763,0 +4764,0 +4765,0 +4766,0 +4767,0 +4768,0 +4769,0 +4770,0 +4771,0 +4772,0 +4773,0 +4774,0 +4775,0 +4776,0 +4777,0 +4778,0 +4779,0 +4780,0 +4781,0 +4782,0 +4783,0 +4784,0 +4785,0 +4786,0 +4787,0 +4788,0 +4789,0 +4790,0 +4791,0 +4792,0 +4793,0 +4794,0 +4795,0 +4796,0 +4797,0 +4798,0 +4799,0 +4800,0 +4801,0 +4802,0 +4803,0 +4804,0 +4805,0 +4806,0 +4807,0 +4808,0 +4809,0 +4810,0 +4811,0 +4812,0 +4813,0 +4814,0 +4815,0 +4816,0 +4817,0 +4818,0 +4819,0 +4820,0 +4821,0 +4822,0 +4823,0 +4824,0 +4825,0 +4826,0 +4827,0 +4828,0 +4829,0 +4830,0 +4831,0 +4832,0 +4833,0 +4834,0 +4835,0 +4836,0 +4837,0 +4838,0 +4839,0 +4840,0 +4841,0 +4842,0 +4843,0 +4844,0 +4845,0 +4846,0 +4847,0 +4848,0 +4849,0 +4850,0 +4851,0 +4852,0 +4853,0 +4854,0 +4855,0 +4856,0 +4857,0 +4858,0 +4859,0 +4860,0 +4861,0 +4862,0 +4863,0 +4864,0 +4865,0 +4866,0 +4867,0 +4868,0 +4869,0 +4870,0 +4871,0 +4872,0 +4873,0 +4874,0 +4875,0 +4876,0 +4877,0 +4878,0 +4879,0 +4880,0 +4881,0 +4882,0 +4883,0 +4884,0 +4885,0 +4886,0 +4887,0 +4888,0 +4889,0 +4890,0 +4891,0 +4892,0 +4893,0 +4894,0 +4895,0 +4896,0 +4897,0 +4898,0 +4899,0 +4900,0 +4901,0 +4902,0 +4903,0 +4904,0 +4905,0 +4906,0 +4907,0 +4908,0 +4909,0 +4910,0 +4911,0 +4912,0 +4913,0 +4914,0 +4915,0 +4916,0 +4917,0 +4918,0 +4919,0 +4920,0 +4921,0 +4922,0 +4923,0 +4924,0 +4925,0 +4926,0 +4927,0 +4928,0 +4929,0 +4930,0 +4931,0 +4932,0 +4933,0 +4934,0 +4935,0 +4936,0 +4937,0 +4938,0 +4939,0 +4940,0 +4941,0 +4942,0 +4943,0 +4944,0 +4945,0 +4946,0 +4947,0 +4948,0 +4949,0 +4950,0 +4951,0 +4952,0 +4953,0 +4954,0 +4955,0 +4956,0 +4957,0 +4958,0 +4959,0 +4960,0 +4961,0 +4962,0 +4963,0 +4964,0 +4965,0 +4966,0 +4967,0 +4968,0 +4969,0 +4970,0 +4971,0 +4972,0 +4973,0 +4974,0 +4975,0 +4976,0 +4977,0 +4978,0 +4979,0 +4980,0 +4981,0 +4982,0 +4983,0 +4984,0 +4985,0 +4986,0 +4987,0 +4988,0 +4989,0 +4990,0 +4991,0 +4992,0 +4993,0 +4994,0 +4995,0 +4996,0 +4997,0 +4998,0 +4999,0 +5000,0 +5001,0 +5002,0 +5003,0 +5004,0 +5005,0 +5006,0 +5007,0 +5008,0 +5009,0 +5010,0 +5011,0 +5012,0 +5013,0 +5014,0 +5015,0 +5016,0 +5017,0 +5018,0 +5019,0 +5020,0 +5021,0 +5022,0 +5023,0 +5024,0 +5025,0 +5026,0 +5027,0 +5028,0 +5029,0 +5030,0 +5031,0 +5032,0 +5033,0 +5034,0 +5035,0 +5036,0 +5037,0 +5038,0 +5039,0 +5040,0 +5041,0 +5042,0 +5043,0 +5044,0 +5045,0 +5046,0 +5047,0 +5048,0 +5049,0 +5050,0 +5051,0 +5052,0 +5053,0 +5054,0 +5055,0 +5056,0 +5057,0 +5058,0 +5059,0 +5060,0 +5061,0 +5062,0 +5063,0 +5064,0 +5065,0 +5066,0 +5067,0 +5068,0 +5069,0 +5070,0 +5071,0 +5072,0 +5073,0 +5074,0 +5075,0 +5076,0 +5077,0 +5078,0 +5079,0 +5080,0 +5081,0 +5082,0 +5083,0 +5084,0 +5085,0 +5086,0 +5087,0 +5088,0 +5089,0 +5090,0 +5091,0 +5092,0 +5093,0 +5094,0 +5095,0 +5096,0 +5097,0 +5098,0 +5099,0 +5100,0 +5101,0 +5102,0 +5103,0 +5104,0 +5105,0 +5106,0 +5107,0 +5108,0 +5109,0 +5110,0 +5111,0 +5112,0 +5113,0 +5114,0 +5115,0 +5116,0 +5117,0 +5118,0 +5119,0 +5120,0 +5121,0 +5122,0 +5123,0 +5124,0 +5125,0 +5126,0 +5127,0 +5128,0 +5129,0 +5130,0 +5131,0 +5132,0 +5133,0 +5134,0 +5135,0 +5136,0 +5137,0 +5138,0 +5139,0 +5140,0 +5141,0 +5142,0 +5143,0 +5144,0 +5145,0 +5146,0 +5147,0 +5148,0 +5149,0 +5150,0 +5151,0 +5152,0 +5153,0 +5154,0 +5155,0 +5156,0 +5157,0 +5158,0 +5159,0 +5160,0 +5161,0 +5162,0 +5163,0 +5164,0 +5165,0 +5166,0 +5167,0 +5168,0 +5169,0 +5170,0 +5171,0 +5172,0 +5173,0 +5174,0 +5175,0 +5176,0 +5177,0 +5178,0 +5179,0 +5180,0 +5181,0 +5182,0 +5183,0 +5184,0 +5185,0 +5186,0 +5187,0 +5188,0 +5189,0 +5190,0 +5191,0 +5192,0 +5193,0 +5194,0 +5195,0 +5196,0 +5197,0 +5198,0 +5199,0 +5200,0 +5201,0 +5202,0 +5203,0 +5204,0 +5205,0 +5206,0 +5207,0 +5208,0 +5209,0 +5210,0 +5211,0 +5212,0 +5213,0 +5214,0 +5215,0 +5216,0 +5217,0 +5218,0 +5219,0 +5220,0 +5221,0 +5222,0 +5223,0 +5224,0 +5225,0 +5226,0 +5227,0 +5228,0 +5229,0 +5230,0 +5231,0 +5232,0 +5233,0 +5234,0 +5235,0 +5236,0 +5237,0 +5238,0 +5239,0 +5240,0 +5241,0 +5242,0 +5243,0 +5244,0 +5245,0 +5246,0 +5247,0 +5248,0 +5249,0 +5250,0 +5251,0 +5252,0 +5253,0 +5254,0 +5255,0 +5256,0 +5257,0 +5258,0 +5259,0 +5260,0 +5261,0 +5262,0 +5263,0 +5264,0 +5265,0 +5266,0 +5267,0 +5268,0 +5269,0 +5270,0 +5271,0 +5272,0 +5273,0 +5274,0 +5275,0 +5276,0 +5277,0 +5278,0 +5279,0 +5280,0 +5281,0 +5282,0 +5283,0 +5284,0 +5285,0 +5286,0 +5287,0 +5288,0 +5289,0 +5290,0 +5291,0 +5292,0 +5293,0 +5294,0 +5295,0 +5296,0 +5297,0 +5298,0 +5299,0 +5300,0 +5301,0 +5302,0 +5303,0 +5304,0 +5305,0 +5306,0 +5307,0 +5308,0 +5309,0 +5310,0 +5311,0 +5312,0 +5313,0 +5314,0 +5315,0 +5316,0 +5317,0 +5318,0 +5319,0 +5320,0 +5321,0 +5322,0 +5323,0 +5324,0 +5325,0 +5326,0 +5327,0 +5328,0 +5329,0 +5330,0 +5331,0 +5332,0 +5333,0 +5334,0 +5335,0 +5336,0 +5337,0 +5338,0 +5339,0 +5340,0 +5341,0 +5342,0 +5343,0 +5344,0 +5345,0 +5346,0 +5347,0 +5348,0 +5349,0 +5350,0 +5351,0 +5352,0 +5353,0 +5354,0 +5355,0 +5356,0 +5357,0 +5358,0 +5359,0 +5360,0 +5361,0 +5362,0 +5363,0 +5364,0 +5365,0 +5366,0 +5367,0 +5368,0 +5369,0 +5370,0 +5371,0 +5372,0 +5373,0 +5374,0 +5375,0 +5376,0 +5377,0 +5378,0 +5379,0 +5380,0 +5381,0 +5382,0 +5383,0 +5384,0 +5385,0 +5386,0 +5387,0 +5388,0 +5389,0 +5390,0 +5391,0 +5392,0 +5393,0 +5394,0 +5395,0 +5396,0 +5397,0 +5398,0 +5399,0 +5400,0 +5401,0 +5402,0 +5403,0 +5404,0 +5405,0 +5406,0 +5407,0 +5408,0 +5409,0 +5410,0 +5411,0 +5412,0 +5413,0 +5414,0 +5415,0 +5416,0 +5417,0 +5418,0 +5419,0 +5420,0 +5421,0 +5422,0 +5423,0 +5424,0 +5425,0 +5426,0 +5427,0 +5428,0 +5429,0 +5430,0 +5431,0 +5432,0 +5433,0 +5434,0 +5435,0 +5436,0 +5437,0 +5438,0 +5439,0 +5440,0 +5441,0 +5442,0 +5443,0 +5444,0 +5445,0 +5446,0 +5447,0 +5448,0 +5449,0 +5450,0 +5451,0 +5452,0 +5453,0 +5454,0 +5455,0 +5456,0 +5457,0 +5458,0 +5459,0 +5460,0 +5461,0 +5462,0 +5463,0 +5464,0 +5465,0 +5466,0 +5467,0 +5468,0 +5469,0 +5470,0 +5471,0 +5472,0 +5473,0 +5474,0 +5475,0 +5476,0 +5477,0 +5478,0 +5479,0 +5480,0 +5481,0 +5482,0 +5483,0 +5484,0 +5485,0 +5486,0 +5487,0 +5488,0 +5489,0 +5490,0 +5491,0 +5492,0 +5493,0 +5494,0 +5495,0 +5496,0 +5497,0 +5498,0 +5499,0 +5500,0 +5501,0 +5502,0 +5503,0 +5504,0 +5505,0 +5506,0 +5507,0 +5508,0 +5509,0 +5510,0 +5511,0 +5512,0 +5513,0 +5514,0 +5515,0 +5516,0 +5517,0 +5518,0 +5519,0 +5520,0 +5521,0 +5522,0 +5523,0 +5524,0 +5525,0 +5526,0 +5527,0 +5528,0 +5529,0 +5530,0 +5531,0 +5532,0 +5533,0 +5534,0 +5535,0 +5536,0 +5537,0 +5538,0 +5539,0 +5540,0 +5541,0 +5542,0 +5543,0 +5544,0 +5545,0 +5546,0 +5547,0 +5548,0 +5549,0 +5550,0 +5551,0 +5552,0 +5553,0 +5554,0 +5555,0 +5556,0 +5557,0 +5558,0 +5559,0 +5560,0 +5561,0 +5562,0 +5563,0 +5564,0 +5565,0 +5566,0 +5567,0 +5568,0 +5569,0 +5570,0 +5571,0 +5572,0 +5573,0 +5574,0 +5575,0 +5576,0 +5577,0 +5578,0 +5579,0 +5580,0 +5581,0 +5582,0 +5583,0 +5584,0 +5585,0 +5586,0 +5587,0 +5588,0 +5589,0 +5590,0 +5591,0 +5592,0 +5593,0 +5594,0 +5595,0 +5596,0 +5597,0 +5598,0 +5599,0 +5600,0 +5601,0 +5602,0 +5603,0 +5604,0 +5605,0 +5606,0 +5607,0 +5608,0 +5609,0 +5610,0 +5611,0 +5612,0 +5613,0 +5614,0 +5615,0 +5616,0 +5617,0 +5618,0 +5619,0 +5620,0 +5621,0 +5622,0 +5623,0 +5624,0 +5625,0 +5626,0 +5627,0 +5628,0 +5629,0 +5630,0 +5631,0 +5632,0 +5633,0 +5634,0 +5635,0 +5636,0 +5637,0 +5638,0 +5639,0 +5640,0 +5641,0 +5642,0 +5643,0 +5644,0 +5645,0 +5646,0 +5647,0 +5648,0 +5649,0 +5650,0 +5651,0 +5652,0 +5653,0 +5654,0 +5655,0 +5656,0 +5657,0 +5658,0 +5659,0 +5660,0 +5661,0 +5662,0 +5663,0 +5664,0 +5665,0 +5666,0 +5667,0 +5668,0 +5669,0 +5670,0 +5671,0 +5672,0 +5673,0 +5674,0 +5675,0 +5676,0 +5677,0 +5678,0 +5679,0 +5680,0 +5681,0 +5682,0 +5683,0 +5684,0 +5685,0 +5686,0 +5687,0 +5688,0 +5689,0 +5690,0 +5691,0 +5692,0 +5693,0 +5694,0 +5695,0 +5696,0 +5697,0 +5698,0 +5699,0 +5700,0 +5701,0 +5702,0 +5703,0 +5704,0 +5705,0 +5706,0 +5707,0 +5708,0 +5709,0 +5710,0 +5711,0 +5712,0 +5713,0 +5714,0 +5715,0 +5716,0 +5717,0 +5718,0 +5719,0 +5720,0 +5721,0 +5722,0 +5723,0 +5724,0 +5725,0 +5726,0 +5727,0 +5728,0 +5729,0 +5730,0 +5731,0 +5732,0 +5733,0 +5734,0 +5735,0 +5736,0 +5737,0 +5738,0 +5739,0 +5740,0 +5741,0 +5742,0 +5743,0 +5744,0 +5745,0 +5746,0 +5747,0 +5748,0 +5749,0 +5750,0 +5751,0 +5752,0 +5753,0 +5754,0 +5755,0 +5756,0 +5757,0 +5758,0 +5759,0 +5760,0 +5761,0 +5762,0 +5763,0 +5764,0 +5765,0 +5766,0 +5767,0 +5768,0 +5769,0 +5770,0 +5771,0 +5772,0 +5773,0 +5774,0 +5775,0 +5776,0 +5777,0 +5778,0 +5779,0 +5780,0 +5781,0 +5782,0 +5783,0 +5784,0 +5785,0 +5786,0 +5787,0 +5788,0 +5789,0 +5790,0 +5791,0 +5792,0 +5793,0 +5794,0 +5795,0 +5796,0 +5797,0 +5798,0 +5799,0 +5800,0 +5801,0 +5802,0 +5803,0 +5804,0 +5805,0 +5806,0 +5807,0 +5808,0 +5809,0 +5810,0 +5811,0 +5812,0 +5813,0 +5814,0 +5815,0 +5816,0 +5817,0 +5818,0 +5819,0 +5820,0 +5821,0 +5822,0 +5823,0 +5824,0 +5825,0 +5826,0 +5827,0 +5828,0 +5829,0 +5830,0 +5831,0 +5832,0 +5833,0 +5834,0 +5835,0 +5836,0 +5837,0 +5838,0 +5839,0 +5840,0 +5841,0 +5842,0 +5843,0 +5844,0 +5845,0 +5846,0 +5847,0 +5848,0 +5849,0 +5850,0 +5851,0 +5852,0 +5853,0 +5854,0 +5855,0 +5856,0 +5857,0 +5858,0 +5859,0 +5860,0 +5861,0 +5862,0 +5863,0 +5864,0 +5865,0 +5866,0 +5867,0 +5868,0 +5869,0 +5870,0 +5871,0 +5872,0 +5873,0 +5874,0 +5875,0 +5876,0 +5877,0 +5878,0 +5879,0 +5880,0 +5881,0 +5882,0 +5883,0 +5884,0 +5885,0 +5886,0 +5887,0 +5888,0 +5889,0 +5890,0 +5891,0 +5892,0 +5893,0 +5894,0 +5895,0 +5896,0 +5897,0 +5898,0 +5899,0 +5900,0 +5901,0 +5902,0 +5903,0 +5904,0 +5905,0 +5906,0 +5907,0 +5908,0 +5909,0 +5910,0 +5911,0 +5912,0 +5913,0 +5914,0 +5915,0 +5916,0 +5917,0 +5918,0 +5919,0 +5920,0 +5921,0 +5922,0 +5923,0 +5924,0 +5925,0 +5926,0 +5927,0 +5928,0 +5929,0 +5930,0 +5931,0 +5932,0 +5933,0 +5934,0 +5935,0 +5936,0 +5937,0 +5938,0 +5939,0 +5940,0 +5941,0 +5942,0 +5943,0 +5944,0 +5945,0 +5946,0 +5947,0 +5948,0 +5949,0 +5950,0 +5951,0 +5952,0 +5953,0 +5954,0 +5955,0 +5956,0 +5957,0 +5958,0 +5959,0 +5960,0 +5961,0 +5962,0 +5963,0 +5964,0 +5965,0 +5966,0 +5967,0 +5968,0 +5969,0 +5970,0 +5971,0 +5972,0 +5973,0 +5974,0 +5975,0 +5976,0 +5977,0 +5978,0 +5979,0 +5980,0 +5981,0 +5982,0 +5983,0 +5984,0 +5985,0 +5986,0 +5987,0 +5988,0 +5989,0 +5990,0 +5991,0 +5992,0 +5993,0 +5994,0 +5995,0 +5996,0 +5997,0 +5998,0 +5999,0 +6000,0 +6001,0 +6002,0 +6003,0 +6004,0 +6005,0 +6006,0 +6007,0 +6008,0 +6009,0 +6010,0 +6011,0 +6012,0 +6013,0 +6014,0 +6015,0 +6016,0 +6017,0 +6018,0 +6019,0 +6020,0 +6021,0 +6022,0 +6023,0 +6024,0 +6025,0 +6026,0 +6027,0 +6028,0 +6029,0 +6030,0 +6031,0 +6032,0 +6033,0 +6034,0 +6035,0 +6036,0 +6037,0 +6038,0 +6039,0 +6040,0 +6041,0 +6042,0 +6043,0 +6044,0 +6045,0 +6046,0 +6047,0 +6048,0 +6049,0 +6050,0 +6051,0 +6052,0 +6053,0 +6054,0 +6055,0 +6056,0 +6057,0 +6058,0 +6059,0 +6060,0 +6061,0 +6062,0 +6063,0 +6064,0 +6065,0 +6066,0 +6067,0 +6068,0 +6069,0 +6070,0 +6071,0 +6072,0 +6073,0 +6074,0 +6075,0 +6076,0 +6077,0 +6078,0 +6079,0 +6080,0 +6081,0 +6082,0 +6083,0 +6084,0 +6085,0 +6086,0 +6087,0 +6088,0 +6089,0 +6090,0 +6091,0 +6092,0 +6093,0 +6094,0 +6095,0 +6096,0 +6097,0 +6098,0 +6099,0 +6100,0 +6101,0 +6102,0 +6103,0 +6104,0 +6105,0 +6106,0 +6107,0 +6108,0 +6109,0 +6110,0 +6111,0 +6112,0 +6113,0 +6114,0 +6115,0 +6116,0 +6117,0 +6118,0 +6119,0 +6120,0 +6121,0 +6122,0 +6123,0 +6124,0 +6125,0 +6126,0 +6127,0 +6128,0 +6129,0 +6130,0 +6131,0 +6132,0 +6133,0 +6134,0 +6135,0 +6136,0 +6137,0 +6138,0 +6139,0 +6140,0 +6141,0 +6142,0 +6143,0 +6144,0 +6145,0 +6146,0 +6147,0 +6148,0 +6149,0 +6150,0 +6151,0 +6152,0 +6153,0 +6154,0 +6155,0 +6156,0 +6157,0 +6158,0 +6159,0 +6160,0 +6161,0 +6162,0 +6163,0 +6164,0 +6165,0 +6166,0 +6167,0 +6168,0 +6169,0 +6170,0 +6171,0 +6172,0 +6173,0 +6174,0 +6175,0 +6176,0 +6177,0 +6178,0 +6179,0 +6180,0 +6181,0 +6182,0 +6183,0 +6184,0 +6185,0 +6186,0 +6187,0 +6188,0 +6189,0 +6190,0 +6191,0 +6192,0 +6193,0 +6194,0 +6195,0 +6196,0 +6197,0 +6198,0 +6199,0 +6200,0 +6201,0 +6202,0 +6203,0 +6204,0 +6205,0 +6206,0 +6207,0 +6208,0 +6209,0 +6210,0 +6211,0 +6212,0 +6213,0 +6214,0 +6215,0 +6216,0 +6217,0 +6218,0 +6219,0 +6220,0 +6221,0 +6222,0 +6223,0 +6224,0 +6225,0 +6226,0 +6227,0 +6228,0 +6229,0 +6230,0 +6231,0 +6232,0 +6233,0 +6234,0 +6235,0 +6236,0 +6237,0 +6238,0 +6239,0 +6240,0 +6241,0 +6242,0 +6243,0 +6244,0 +6245,0 +6246,0 +6247,0 +6248,0 +6249,0 +6250,0 +6251,0 +6252,0 +6253,0 +6254,0 +6255,0 +6256,0 +6257,0 +6258,0 +6259,0 +6260,0 +6261,0 +6262,0 +6263,0 +6264,0 +6265,0 +6266,0 +6267,0 +6268,0 +6269,0 +6270,0 +6271,0 +6272,0 +6273,0 +6274,0 +6275,0 +6276,0 +6277,0 +6278,0 +6279,0 +6280,0 +6281,0 +6282,0 +6283,0 +6284,0 +6285,0 +6286,0 +6287,0 +6288,0 +6289,0 +6290,0 +6291,0 +6292,0 +6293,0 +6294,0 +6295,0 +6296,0 +6297,0 +6298,0 +6299,0 +6300,0 +6301,0 +6302,0 +6303,0 +6304,0 +6305,0 +6306,0 +6307,0 +6308,0 +6309,0 +6310,0 +6311,0 +6312,0 +6313,0 +6314,0 +6315,0 +6316,0 +6317,0 +6318,0 +6319,0 +6320,0 +6321,0 +6322,0 +6323,0 +6324,0 +6325,0 +6326,0 +6327,0 +6328,0 +6329,0 +6330,0 +6331,0 +6332,0 +6333,0 +6334,0 +6335,0 +6336,0 +6337,0 +6338,0 +6339,0 +6340,0 +6341,0 +6342,0 +6343,0 +6344,0 +6345,0 +6346,0 +6347,0 +6348,0 +6349,0 +6350,0 +6351,0 +6352,0 +6353,0 +6354,0 +6355,0 +6356,0 +6357,0 +6358,0 +6359,0 +6360,0 +6361,0 +6362,0 +6363,0 +6364,0 +6365,0 +6366,0 +6367,0 +6368,0 +6369,0 +6370,0 +6371,0 +6372,0 +6373,0 +6374,0 +6375,0 +6376,0 +6377,0 +6378,0 +6379,0 +6380,0 +6381,0 +6382,0 +6383,0 +6384,0 +6385,0 +6386,0 +6387,0 +6388,0 +6389,0 +6390,0 +6391,0 +6392,0 +6393,0 +6394,0 +6395,0 +6396,0 +6397,0 +6398,0 +6399,0 +6400,0 +6401,0 +6402,0 +6403,0 +6404,0 +6405,0 +6406,0 +6407,0 +6408,0 +6409,0 +6410,0 +6411,0 +6412,0 +6413,0 +6414,0 +6415,0 +6416,0 +6417,0 +6418,0 +6419,0 +6420,0 +6421,0 +6422,0 +6423,0 +6424,0 +6425,0 +6426,0 +6427,0 +6428,0 +6429,0 +6430,0 +6431,0 +6432,0 +6433,0 +6434,0 +6435,0 +6436,0 +6437,0 +6438,0 +6439,0 +6440,0 +6441,0 +6442,0 +6443,0 +6444,0 +6445,0 +6446,0 +6447,0 +6448,0 +6449,0 +6450,0 +6451,0 +6452,0 +6453,0 +6454,0 +6455,0 +6456,0 +6457,0 +6458,0 +6459,0 +6460,0 +6461,0 +6462,0 +6463,0 +6464,0 +6465,0 +6466,0 +6467,0 +6468,0 +6469,0 +6470,0 +6471,0 +6472,0 +6473,0 +6474,0 +6475,0 +6476,0 +6477,0 +6478,0 +6479,0 +6480,0 +6481,0 +6482,0 +6483,0 +6484,0 +6485,0 +6486,0 +6487,0 +6488,0 +6489,0 +6490,0 +6491,0 +6492,0 +6493,0 +6494,0 +6495,0 +6496,0 +6497,0 +6498,0 +6499,0 +6500,0 +6501,0 +6502,0 +6503,0 +6504,0 +6505,0 +6506,0 +6507,0 +6508,0 +6509,0 +6510,0 +6511,0 +6512,0 +6513,0 +6514,0 +6515,0 +6516,0 +6517,0 +6518,0 +6519,0 +6520,0 +6521,0 +6522,0 +6523,0 +6524,0 +6525,0 +6526,0 +6527,0 +6528,0 +6529,0 +6530,0 +6531,0 +6532,0 +6533,0 +6534,0 +6535,0 +6536,0 +6537,0 +6538,0 +6539,0 +6540,0 +6541,0 +6542,0 +6543,0 +6544,0 +6545,0 +6546,0 +6547,0 +6548,0 +6549,0 +6550,0 +6551,0 +6552,0 +6553,0 +6554,0 +6555,0 +6556,0 +6557,0 +6558,0 +6559,0 +6560,0 +6561,0 +6562,0 +6563,0 +6564,0 +6565,0 +6566,0 +6567,0 +6568,0 +6569,0 +6570,0 +6571,0 +6572,0 +6573,0 +6574,0 +6575,0 +6576,0 +6577,0 +6578,0 +6579,0 +6580,0 +6581,0 +6582,0 +6583,0 +6584,0 +6585,0 +6586,0 +6587,0 +6588,0 +6589,0 +6590,0 +6591,0 +6592,0 +6593,0 +6594,0 +6595,0 +6596,0 +6597,0 +6598,0 +6599,0 +6600,0 +6601,0 +6602,0 +6603,0 +6604,0 +6605,0 +6606,0 +6607,0 +6608,0 +6609,0 +6610,0 +6611,0 +6612,0 +6613,0 +6614,0 +6615,0 +6616,0 +6617,0 +6618,0 +6619,0 +6620,0 +6621,0 +6622,0 +6623,0 +6624,0 +6625,0 +6626,0 +6627,0 +6628,0 +6629,0 +6630,0 +6631,0 +6632,0 +6633,0 +6634,0 +6635,0 +6636,0 +6637,0 +6638,0 +6639,0 +6640,0 +6641,0 +6642,0 +6643,0 +6644,0 +6645,0 +6646,0 +6647,0 +6648,0 +6649,0 +6650,0 +6651,0 +6652,0 +6653,0 +6654,0 +6655,0 +6656,0 +6657,0 +6658,0 +6659,0 +6660,0 +6661,0 +6662,0 +6663,0 +6664,0 +6665,0 +6666,0 +6667,0 +6668,0 +6669,0 +6670,0 +6671,0 +6672,0 +6673,0 +6674,0 +6675,0 +6676,0 +6677,0 +6678,0 +6679,0 +6680,0 +6681,0 +6682,0 +6683,0 +6684,0 +6685,0 +6686,0 +6687,0 +6688,0 +6689,0 +6690,0 +6691,0 +6692,0 +6693,0 +6694,0 +6695,0 +6696,0 +6697,0 +6698,0 +6699,0 +6700,0 +6701,0 +6702,0 +6703,0 +6704,0 +6705,0 +6706,0 +6707,0 +6708,0 +6709,0 +6710,0 +6711,0 +6712,0 +6713,0 +6714,0 +6715,0 +6716,0 +6717,0 +6718,0 +6719,0 +6720,0 +6721,0 +6722,0 +6723,0 +6724,0 +6725,0 +6726,0 +6727,0 +6728,0 +6729,0 +6730,0 +6731,0 +6732,0 +6733,0 +6734,0 +6735,0 +6736,0 +6737,0 +6738,0 +6739,0 +6740,0 +6741,0 +6742,0 +6743,0 +6744,0 +6745,0 +6746,0 +6747,0 +6748,0 +6749,0 +6750,0 +6751,0 +6752,0 +6753,0 +6754,0 +6755,0 +6756,0 +6757,0 +6758,0 +6759,0 +6760,0 +6761,0 +6762,0 +6763,0 +6764,0 +6765,0 +6766,0 +6767,0 +6768,0 +6769,0 +6770,0 +6771,0 +6772,0 +6773,0 +6774,0 +6775,0 +6776,0 +6777,0 +6778,0 +6779,0 +6780,0 +6781,0 +6782,0 +6783,0 +6784,0 +6785,0 +6786,0 +6787,0 +6788,0 +6789,0 +6790,0 +6791,0 +6792,0 +6793,0 +6794,0 +6795,0 +6796,0 +6797,0 +6798,0 +6799,0 +6800,0 +6801,0 +6802,0 +6803,0 +6804,0 +6805,0 +6806,0 +6807,0 +6808,0 +6809,0 +6810,0 +6811,0 +6812,0 +6813,0 +6814,0 +6815,0 +6816,0 +6817,0 +6818,0 +6819,0 +6820,0 +6821,0 +6822,0 +6823,0 +6824,0 +6825,0 +6826,0 +6827,0 +6828,0 +6829,0 +6830,0 +6831,0 +6832,0 +6833,0 +6834,0 +6835,0 +6836,0 +6837,0 +6838,0 +6839,0 +6840,0 +6841,0 +6842,0 +6843,0 +6844,0 +6845,0 +6846,0 +6847,0 +6848,0 +6849,0 +6850,0 +6851,0 +6852,0 +6853,0 +6854,0 +6855,0 +6856,0 +6857,0 +6858,0 +6859,0 +6860,0 +6861,0 +6862,0 +6863,0 +6864,0 +6865,0 +6866,0 +6867,0 +6868,0 +6869,0 +6870,0 +6871,0 +6872,0 +6873,0 +6874,0 +6875,0 +6876,0 +6877,0 +6878,0 +6879,0 +6880,0 +6881,0 +6882,0 +6883,0 +6884,0 +6885,0 +6886,0 +6887,0 +6888,0 +6889,0 +6890,0 +6891,0 +6892,0 +6893,0 +6894,0 +6895,0 +6896,0 +6897,0 +6898,0 +6899,0 +6900,0 +6901,0 +6902,0 +6903,0 +6904,0 +6905,0 +6906,0 +6907,0 +6908,0 +6909,0 +6910,0 +6911,0 +6912,0 +6913,0 +6914,0 +6915,0 +6916,0 +6917,0 +6918,0 +6919,0 +6920,0 +6921,0 +6922,0 +6923,0 +6924,0 +6925,0 +6926,0 +6927,0 +6928,0 +6929,0 +6930,0 +6931,0 +6932,0 +6933,0 +6934,0 +6935,0 +6936,0 +6937,0 +6938,0 +6939,0 +6940,0 +6941,0 +6942,0 +6943,0 +6944,0 +6945,0 +6946,0 +6947,0 +6948,0 +6949,0 +6950,0 +6951,0 +6952,0 +6953,0 +6954,0 +6955,0 +6956,0 +6957,0 +6958,0 +6959,0 +6960,0 +6961,0 +6962,0 +6963,0 +6964,0 +6965,0 +6966,0 +6967,0 +6968,0 +6969,0 +6970,0 +6971,0 +6972,0 +6973,0 +6974,0 +6975,0 +6976,0 +6977,0 +6978,0 +6979,0 +6980,0 +6981,0 +6982,0 +6983,0 +6984,0 +6985,0 +6986,0 +6987,0 +6988,0 +6989,0 +6990,0 +6991,0 +6992,0 +6993,0 +6994,0 +6995,0 +6996,0 +6997,0 +6998,0 +6999,0 +7000,0 +7001,0 +7002,0 +7003,0 +7004,0 +7005,0 +7006,0 +7007,0 +7008,0 +7009,0 +7010,0 +7011,0 +7012,0 +7013,0 +7014,0 +7015,0 +7016,0 +7017,0 +7018,0 +7019,0 +7020,0 +7021,0 +7022,0 +7023,0 +7024,0 +7025,0 +7026,0 +7027,0 +7028,0 +7029,0 +7030,0 +7031,0 +7032,0 +7033,0 +7034,0 +7035,0 +7036,0 +7037,0 +7038,0 +7039,0 +7040,0 +7041,0 +7042,0 +7043,0 +7044,0 +7045,0 +7046,0 +7047,0 +7048,0 +7049,0 +7050,0 +7051,0 +7052,0 +7053,0 +7054,0 +7055,0 +7056,0 +7057,0 +7058,0 +7059,0 +7060,0 +7061,0 +7062,0 +7063,0 +7064,0 +7065,0 +7066,0 +7067,0 +7068,0 +7069,0 +7070,0 +7071,0 +7072,0 +7073,0 +7074,0 +7075,0 +7076,0 +7077,0 +7078,0 +7079,0 +7080,0 +7081,0 +7082,0 +7083,0 +7084,0 +7085,0 +7086,0 +7087,0 +7088,0 +7089,0 +7090,0 +7091,0 +7092,0 +7093,0 +7094,0 +7095,0 +7096,0 +7097,0 +7098,0 +7099,0 +7100,0 +7101,0 +7102,0 +7103,0 +7104,0 +7105,0 +7106,0 +7107,0 +7108,0 +7109,0 +7110,0 +7111,0 +7112,0 +7113,0 +7114,0 +7115,0 +7116,0 +7117,0 +7118,0 +7119,0 +7120,0 +7121,0 +7122,0 +7123,0 +7124,0 +7125,0 +7126,0 +7127,0 +7128,0 +7129,0 +7130,0 +7131,0 +7132,0 +7133,0 +7134,0 +7135,0 +7136,0 +7137,0 +7138,0 +7139,0 +7140,0 +7141,0 +7142,0 +7143,0 +7144,0 +7145,0 +7146,0 +7147,0 +7148,0 +7149,0 +7150,0 +7151,0 +7152,0 +7153,0 +7154,0 +7155,0 +7156,0 +7157,0 +7158,0 +7159,0 +7160,0 +7161,0 +7162,0 +7163,0 +7164,0 +7165,0 +7166,0 +7167,0 +7168,0 +7169,0 +7170,0 +7171,0 +7172,0 +7173,0 +7174,0 +7175,0 +7176,0 +7177,0 +7178,0 +7179,0 +7180,0 +7181,0 +7182,0 +7183,0 +7184,0 +7185,0 +7186,0 +7187,0 +7188,0 +7189,0 +7190,0 +7191,0 +7192,0 +7193,0 +7194,0 +7195,0 +7196,0 +7197,0 +7198,0 +7199,0 +7200,0 +7201,0 +7202,0 +7203,0 +7204,0 +7205,0 +7206,0 +7207,0 +7208,0 +7209,0 +7210,0 +7211,0 +7212,0 +7213,0 +7214,0 +7215,0 +7216,0 +7217,0 +7218,0 +7219,0 +7220,0 +7221,0 +7222,0 +7223,0 +7224,0 +7225,0 +7226,0 +7227,0 +7228,0 +7229,0 +7230,0 +7231,0 +7232,0 +7233,0 +7234,0 +7235,0 +7236,0 +7237,0 +7238,0 +7239,0 +7240,0 +7241,0 +7242,0 +7243,0 +7244,0 +7245,0 +7246,0 +7247,0 +7248,0 +7249,0 +7250,0 +7251,0 +7252,0 +7253,0 +7254,0 +7255,0 +7256,0 +7257,0 +7258,0 +7259,0 +7260,0 +7261,0 +7262,0 +7263,0 +7264,0 +7265,0 +7266,0 +7267,0 +7268,0 +7269,0 +7270,0 +7271,0 +7272,0 +7273,0 +7274,0 +7275,0 +7276,0 +7277,0 +7278,0 +7279,0 +7280,0 +7281,0 +7282,0 +7283,0 +7284,0 +7285,0 +7286,0 +7287,0 +7288,0 +7289,0 +7290,0 +7291,0 +7292,0 +7293,0 +7294,0 +7295,0 +7296,0 +7297,0 +7298,0 +7299,0 +7300,0 +7301,0 +7302,0 +7303,0 +7304,0 +7305,0 +7306,0 +7307,0 +7308,0 +7309,0 +7310,0 +7311,0 +7312,0 +7313,0 +7314,0 +7315,0 +7316,0 +7317,0 +7318,0 +7319,0 +7320,0 +7321,0 +7322,0 +7323,0 +7324,0 +7325,0 +7326,0 +7327,0 +7328,0 +7329,0 +7330,0 +7331,0 +7332,0 +7333,0 +7334,0 +7335,0 +7336,0 +7337,0 +7338,0 +7339,0 +7340,0 +7341,0 +7342,0 +7343,0 +7344,0 +7345,0 +7346,0 +7347,0 +7348,0 +7349,0 +7350,0 +7351,0 +7352,0 +7353,0 +7354,0 +7355,0 +7356,0 +7357,0 +7358,0 +7359,0 +7360,0 +7361,0 +7362,0 +7363,0 +7364,0 +7365,0 +7366,0 +7367,0 +7368,0 +7369,0 +7370,0 +7371,0 +7372,0 +7373,0 +7374,0 +7375,0 +7376,0 +7377,0 +7378,0 +7379,0 +7380,0 +7381,0 +7382,0 +7383,0 +7384,0 +7385,0 +7386,0 +7387,0 +7388,0 +7389,0 +7390,0 +7391,0 +7392,0 +7393,0 +7394,0 +7395,0 +7396,0 +7397,0 +7398,0 +7399,0 +7400,0 +7401,0 +7402,0 +7403,0 +7404,0 +7405,0 +7406,0 +7407,0 +7408,0 +7409,0 +7410,0 +7411,0 +7412,0 +7413,0 +7414,0 +7415,0 +7416,0 +7417,0 +7418,0 +7419,0 +7420,0 +7421,0 +7422,0 +7423,0 +7424,0 +7425,0 +7426,0 +7427,0 +7428,0 +7429,0 +7430,0 +7431,0 +7432,0 +7433,0 +7434,0 +7435,0 +7436,0 +7437,0 +7438,0 +7439,0 +7440,0 +7441,0 +7442,0 +7443,0 +7444,0 +7445,0 +7446,0 +7447,0 +7448,0 +7449,0 +7450,0 +7451,0 +7452,0 +7453,0 +7454,0 +7455,0 +7456,0 +7457,0 +7458,0 +7459,0 +7460,0 +7461,0 +7462,0 +7463,0 +7464,0 +7465,0 +7466,0 +7467,0 +7468,0 +7469,0 +7470,0 +7471,0 +7472,0 +7473,0 +7474,0 +7475,0 +7476,0 +7477,0 +7478,0 +7479,0 +7480,0 +7481,0 +7482,0 +7483,0 +7484,0 +7485,0 +7486,0 +7487,0 +7488,0 +7489,0 +7490,0 +7491,0 +7492,0 +7493,0 +7494,0 +7495,0 +7496,0 +7497,0 +7498,0 +7499,0 +7500,0 +7501,0 +7502,0 +7503,0 +7504,0 +7505,0 +7506,0 +7507,0 +7508,0 +7509,0 +7510,0 +7511,0 +7512,0 +7513,0 +7514,0 +7515,0 +7516,0 +7517,0 +7518,0 +7519,0 +7520,0 +7521,0 +7522,0 +7523,0 +7524,0 +7525,0 +7526,0 +7527,0 +7528,0 +7529,0 +7530,0 +7531,0 +7532,0 +7533,0 +7534,0 +7535,0 +7536,0 +7537,0 +7538,0 +7539,0 +7540,0 +7541,0 +7542,0 +7543,0 +7544,0 +7545,0 +7546,0 +7547,0 +7548,0 +7549,0 +7550,0 +7551,0 +7552,0 +7553,0 +7554,0 +7555,0 +7556,0 +7557,0 +7558,0 +7559,0 +7560,0 +7561,0 +7562,0 +7563,0 +7564,0 +7565,0 +7566,0 +7567,0 +7568,0 +7569,0 +7570,0 +7571,0 +7572,0 +7573,0 +7574,0 +7575,0 +7576,0 +7577,0 +7578,0 +7579,0 +7580,0 +7581,0 +7582,0 +7583,0 +7584,0 +7585,0 +7586,0 +7587,0 +7588,0 +7589,0 +7590,0 +7591,0 +7592,0 +7593,0 +7594,0 +7595,0 +7596,0 +7597,0 +7598,0 +7599,0 +7600,0 +7601,0 +7602,0 +7603,0 +7604,0 +7605,0 +7606,0 +7607,0 +7608,0 +7609,0 +7610,0 +7611,0 +7612,0 +7613,0 +7614,0 +7615,0 +7616,0 +7617,0 +7618,0 +7619,0 +7620,0 +7621,0 +7622,0 +7623,0 +7624,0 +7625,0 +7626,0 +7627,0 +7628,0 +7629,0 +7630,0 +7631,0 +7632,0 +7633,0 +7634,0 +7635,0 +7636,0 +7637,0 +7638,0 +7639,0 +7640,0 +7641,0 +7642,0 +7643,0 +7644,0 +7645,0 +7646,0 +7647,0 +7648,0 +7649,0 +7650,0 +7651,0 +7652,0 +7653,0 +7654,0 +7655,0 +7656,0 +7657,0 +7658,0 +7659,0 +7660,0 +7661,0 +7662,0 +7663,0 +7664,0 +7665,0 +7666,0 +7667,0 +7668,0 +7669,0 +7670,0 +7671,0 +7672,0 +7673,0 +7674,0 +7675,0 +7676,0 +7677,0 +7678,0 +7679,0 +7680,0 +7681,0 +7682,0 +7683,0 +7684,0 +7685,0 +7686,0 +7687,0 +7688,0 +7689,0 +7690,0 +7691,0 +7692,0 +7693,0 +7694,0 +7695,0 +7696,0 +7697,0 +7698,0 +7699,0 +7700,0 +7701,0 +7702,0 +7703,0 +7704,0 +7705,0 +7706,0 +7707,0 +7708,0 +7709,0 +7710,0 +7711,0 +7712,0 +7713,0 +7714,0 +7715,0 +7716,0 +7717,0 +7718,0 +7719,0 +7720,0 +7721,0 +7722,0 +7723,0 +7724,0 +7725,0 +7726,0 +7727,0 +7728,0 +7729,0 +7730,0 +7731,0 +7732,0 +7733,0 +7734,0 +7735,0 +7736,0 +7737,0 +7738,0 +7739,0 +7740,0 +7741,0 +7742,0 +7743,0 +7744,0 +7745,0 +7746,0 +7747,0 +7748,0 +7749,0 +7750,0 +7751,0 +7752,0 +7753,0 +7754,0 +7755,0 +7756,0 +7757,0 +7758,0 +7759,0 +7760,0 +7761,0 +7762,0 +7763,0 +7764,0 +7765,0 +7766,0 +7767,0 +7768,0 +7769,0 +7770,0 +7771,0 +7772,0 +7773,0 +7774,0 +7775,0 +7776,0 +7777,0 +7778,0 +7779,0 +7780,0 +7781,0 +7782,0 +7783,0 +7784,0 +7785,0 +7786,0 +7787,0 +7788,0 +7789,0 +7790,0 +7791,0 +7792,0 +7793,0 +7794,0 +7795,0 +7796,0 +7797,0 +7798,0 +7799,0 +7800,0 +7801,0 +7802,0 +7803,0 +7804,0 +7805,0 +7806,0 +7807,0 +7808,0 +7809,0 +7810,0 +7811,0 +7812,0 +7813,0 +7814,0 +7815,0 +7816,0 +7817,0 +7818,0 +7819,0 +7820,0 +7821,0 +7822,0 +7823,0 +7824,0 +7825,0 +7826,0 +7827,0 +7828,0 +7829,0 +7830,0 +7831,0 +7832,0 +7833,0 +7834,0 +7835,0 +7836,0 +7837,0 +7838,0 +7839,0 +7840,0 +7841,0 +7842,0 +7843,0 +7844,0 +7845,0 +7846,0 +7847,0 +7848,0 +7849,0 +7850,0 +7851,0 +7852,0 +7853,0 +7854,0 +7855,0 +7856,0 +7857,0 +7858,0 +7859,0 +7860,0 +7861,0 +7862,0 +7863,0 +7864,0 +7865,0 +7866,0 +7867,0 +7868,0 +7869,0 +7870,0 +7871,0 +7872,0 +7873,0 +7874,0 +7875,0 +7876,0 +7877,0 +7878,0 +7879,0 +7880,0 +7881,0 +7882,0 +7883,0 +7884,0 +7885,0 +7886,0 +7887,0 +7888,0 +7889,0 +7890,0 +7891,0 +7892,0 +7893,0 +7894,0 +7895,0 +7896,0 +7897,0 +7898,0 +7899,0 +7900,0 +7901,0 +7902,0 +7903,0 +7904,0 +7905,0 +7906,0 +7907,0 +7908,0 +7909,0 +7910,0 +7911,0 +7912,0 +7913,0 +7914,0 +7915,0 +7916,0 +7917,0 +7918,0 +7919,0 +7920,0 +7921,0 +7922,0 +7923,0 +7924,0 +7925,0 +7926,0 +7927,0 +7928,0 +7929,0 +7930,0 +7931,0 +7932,0 +7933,0 +7934,0 +7935,0 +7936,0 +7937,0 +7938,0 +7939,0 +7940,0 +7941,0 +7942,0 +7943,0 +7944,0 +7945,0 +7946,0 +7947,0 +7948,0 +7949,0 +7950,0 +7951,0 +7952,0 +7953,0 +7954,0 +7955,0 +7956,0 +7957,0 +7958,0 +7959,0 +7960,0 +7961,0 +7962,0 +7963,0 +7964,0 +7965,0 +7966,0 +7967,0 +7968,0 +7969,0 +7970,0 +7971,0 +7972,0 +7973,0 +7974,0 +7975,0 +7976,0 +7977,0 +7978,0 +7979,0 +7980,0 +7981,0 +7982,0 +7983,0 +7984,0 +7985,0 +7986,0 +7987,0 +7988,0 +7989,0 +7990,0 +7991,0 +7992,0 +7993,0 +7994,0 +7995,0 +7996,0 +7997,0 +7998,0 +7999,0 +8000,0 +8001,0 +8002,0 +8003,0 +8004,0 +8005,0 +8006,0 +8007,0 +8008,0 +8009,0 +8010,0 +8011,0 +8012,0 +8013,0 +8014,0 +8015,0 +8016,0 +8017,0 +8018,0 +8019,0 +8020,0 +8021,0 +8022,0 +8023,0 +8024,0 +8025,0 +8026,0 +8027,0 +8028,0 +8029,0 +8030,0 +8031,0 +8032,0 +8033,0 +8034,0 +8035,0 +8036,0 +8037,0 +8038,0 +8039,0 +8040,0 +8041,0 +8042,0 +8043,0 +8044,0 +8045,0 +8046,0 +8047,0 +8048,0 +8049,0 +8050,0 +8051,0 +8052,0 +8053,0 +8054,0 +8055,0 +8056,0 +8057,0 +8058,0 +8059,0 +8060,0 +8061,0 +8062,0 +8063,0 +8064,0 +8065,0 +8066,0 +8067,0 +8068,0 +8069,0 +8070,0 +8071,0 +8072,0 +8073,0 +8074,0 +8075,0 +8076,0 +8077,0 +8078,0 +8079,0 +8080,0 +8081,0 +8082,0 +8083,0 +8084,0 +8085,0 +8086,0 +8087,0 +8088,0 +8089,0 +8090,0 +8091,0 +8092,0 +8093,0 +8094,0 +8095,0 +8096,0 +8097,0 +8098,0 +8099,0 +8100,0 +8101,0 +8102,0 +8103,0 +8104,0 +8105,0 +8106,0 +8107,0 +8108,0 +8109,0 +8110,0 +8111,0 +8112,0 +8113,0 +8114,0 +8115,0 +8116,0 +8117,0 +8118,0 +8119,0 +8120,0 +8121,0 +8122,0 +8123,0 +8124,0 +8125,0 +8126,0 +8127,0 +8128,0 +8129,0 +8130,0 +8131,0 +8132,0 +8133,0 +8134,0 +8135,0 +8136,0 +8137,0 +8138,0 +8139,0 +8140,0 +8141,0 +8142,0 +8143,0 +8144,0 +8145,0 +8146,0 +8147,0 +8148,0 +8149,0 +8150,0 +8151,0 +8152,0 +8153,0 +8154,0 +8155,0 +8156,0 +8157,0 +8158,0 +8159,0 +8160,0 +8161,0 +8162,0 +8163,0 +8164,0 +8165,0 +8166,0 +8167,0 +8168,0 +8169,0 +8170,0 +8171,0 +8172,0 +8173,0 +8174,0 +8175,0 +8176,0 +8177,0 +8178,0 +8179,0 +8180,0 +8181,0 +8182,0 +8183,0 +8184,0 +8185,0 +8186,0 +8187,0 +8188,0 +8189,0 +8190,0 +8191,0 +8192,0 +8193,0 +8194,0 +8195,0 +8196,0 +8197,0 +8198,0 +8199,0 +8200,0 +8201,0 +8202,0 +8203,0 +8204,0 +8205,0 +8206,0 +8207,0 +8208,0 +8209,0 +8210,0 +8211,0 +8212,0 +8213,0 +8214,0 +8215,0 +8216,0 +8217,0 +8218,0 +8219,0 +8220,0 +8221,0 +8222,0 +8223,0 +8224,0 +8225,0 +8226,0 +8227,0 +8228,0 +8229,0 +8230,0 +8231,0 +8232,0 +8233,0 +8234,0 +8235,0 +8236,0 +8237,0 +8238,0 +8239,0 +8240,0 +8241,0 +8242,0 +8243,0 +8244,0 +8245,0 +8246,0 +8247,0 +8248,0 +8249,0 +8250,0 +8251,0 +8252,0 +8253,0 +8254,0 +8255,0 +8256,0 +8257,0 +8258,0 +8259,0 +8260,0 +8261,0 +8262,0 +8263,0 +8264,0 +8265,0 +8266,0 +8267,0 +8268,0 +8269,0 +8270,0 +8271,0 +8272,0 +8273,0 +8274,0 +8275,0 +8276,0 +8277,0 +8278,0 +8279,0 +8280,0 +8281,0 +8282,0 +8283,0 +8284,0 +8285,0 +8286,0 +8287,0 +8288,0 +8289,0 +8290,0 +8291,0 +8292,0 +8293,0 +8294,0 +8295,0 +8296,0 +8297,0 +8298,0 +8299,0 +8300,0 +8301,0 +8302,0 +8303,0 +8304,0 +8305,0 +8306,0 +8307,0 +8308,0 +8309,0 +8310,0 +8311,0 +8312,0 +8313,0 +8314,0 +8315,0 +8316,0 +8317,0 +8318,0 +8319,0 +8320,0 +8321,0 +8322,0 +8323,0 +8324,0 +8325,0 +8326,0 +8327,0 +8328,0 +8329,0 +8330,0 +8331,0 +8332,0 +8333,0 +8334,0 +8335,0 +8336,0 +8337,0 +8338,0 +8339,0 +8340,0 +8341,0 +8342,0 +8343,0 +8344,0 +8345,0 +8346,0 +8347,0 +8348,0 +8349,0 +8350,0 +8351,0 +8352,0 +8353,0 +8354,0 +8355,0 +8356,0 +8357,0 +8358,0 +8359,0 +8360,0 +8361,0 +8362,0 +8363,0 +8364,0 +8365,0 +8366,0 +8367,0 +8368,0 +8369,0 +8370,0 +8371,0 +8372,0 +8373,0 +8374,0 +8375,0 +8376,0 +8377,0 +8378,0 +8379,0 +8380,0 +8381,0 +8382,0 +8383,0 +8384,0 +8385,0 +8386,0 +8387,0 +8388,0 +8389,0 +8390,0 +8391,0 +8392,0 +8393,0 +8394,0 +8395,0 +8396,0 +8397,0 +8398,0 +8399,0 +8400,0 +8401,0 +8402,0 +8403,0 +8404,0 +8405,0 +8406,0 +8407,0 +8408,0 +8409,0 +8410,0 +8411,0 +8412,0 +8413,0 +8414,0 +8415,0 +8416,0 +8417,0 +8418,0 +8419,0 +8420,0 +8421,0 +8422,0 +8423,0 +8424,0 +8425,0 +8426,0 +8427,0 +8428,0 +8429,0 +8430,0 +8431,0 +8432,0 +8433,0 +8434,0 +8435,0 +8436,0 +8437,0 +8438,0 +8439,0 +8440,0 +8441,0 +8442,0 +8443,0 +8444,0 +8445,0 +8446,0 +8447,0 +8448,0 +8449,0 +8450,0 +8451,0 +8452,0 +8453,0 +8454,0 +8455,0 +8456,0 +8457,0 +8458,0 +8459,0 +8460,0 +8461,0 +8462,0 +8463,0 +8464,0 +8465,0 +8466,0 +8467,0 +8468,0 +8469,0 +8470,0 +8471,0 +8472,0 +8473,0 +8474,0 +8475,0 +8476,0 +8477,0 +8478,0 +8479,0 +8480,0 +8481,0 +8482,0 +8483,0 +8484,0 +8485,0 +8486,0 +8487,0 +8488,0 +8489,0 +8490,0 +8491,0 +8492,0 +8493,0 +8494,0 +8495,0 +8496,0 +8497,0 +8498,0 +8499,0 +8500,0 +8501,0 +8502,0 +8503,0 +8504,0 +8505,0 +8506,0 +8507,0 +8508,0 +8509,0 +8510,0 +8511,0 +8512,0 +8513,0 +8514,0 +8515,0 +8516,0 +8517,0 +8518,0 +8519,0 +8520,0 +8521,0 +8522,0 +8523,0 +8524,0 +8525,0 +8526,0 +8527,0 +8528,0 +8529,0 +8530,0 +8531,0 +8532,0 +8533,0 +8534,0 +8535,0 +8536,0 +8537,0 +8538,0 +8539,0 +8540,0 +8541,0 +8542,0 +8543,0 +8544,0 +8545,0 +8546,0 +8547,0 +8548,0 +8549,0 +8550,0 +8551,0 +8552,0 +8553,0 +8554,0 +8555,0 +8556,0 +8557,0 +8558,0 +8559,0 +8560,0 +8561,0 +8562,0 +8563,0 +8564,0 +8565,0 +8566,0 +8567,0 +8568,0 +8569,0 +8570,0 +8571,0 +8572,0 +8573,0 +8574,0 +8575,0 +8576,0 +8577,0 +8578,0 +8579,0 +8580,0 +8581,0 +8582,0 +8583,0 +8584,0 +8585,0 +8586,0 +8587,0 +8588,0 +8589,0 +8590,0 +8591,0 +8592,0 +8593,0 +8594,0 +8595,0 +8596,0 +8597,0 +8598,0 +8599,0 +8600,0 +8601,0 +8602,0 +8603,0 +8604,0 +8605,0 +8606,0 +8607,0 +8608,0 +8609,0 +8610,0 +8611,0 +8612,0 +8613,0 +8614,0 +8615,0 +8616,0 +8617,0 +8618,0 +8619,0 +8620,0 +8621,0 +8622,0 +8623,0 +8624,0 +8625,0 +8626,0 +8627,0 +8628,0 +8629,0 +8630,0 +8631,0 +8632,0 +8633,0 +8634,0 +8635,0 +8636,0 +8637,0 +8638,0 +8639,0 +8640,0 +8641,0 +8642,0 +8643,0 +8644,0 +8645,0 +8646,0 +8647,0 +8648,0 +8649,0 +8650,0 +8651,0 +8652,0 +8653,0 +8654,0 +8655,0 +8656,0 +8657,0 +8658,0 +8659,0 +8660,0 +8661,0 +8662,0 +8663,0 +8664,0 +8665,0 +8666,0 +8667,0 +8668,0 +8669,0 +8670,0 +8671,0 +8672,0 +8673,0 +8674,0 +8675,0 +8676,0 +8677,0 +8678,0 +8679,0 +8680,0 +8681,0 +8682,0 +8683,0 +8684,0 +8685,0 +8686,0 +8687,0 +8688,0 +8689,0 +8690,0 +8691,0 +8692,0 +8693,0 +8694,0 +8695,0 +8696,0 +8697,0 +8698,0 +8699,0 +8700,0 +8701,0 +8702,0 +8703,0 +8704,0 +8705,0 +8706,0 +8707,0 +8708,0 +8709,0 +8710,0 +8711,0 +8712,0 +8713,0 +8714,0 +8715,0 +8716,0 +8717,0 +8718,0 +8719,0 +8720,0 +8721,0 +8722,0 +8723,0 +8724,0 +8725,0 +8726,0 +8727,0 +8728,0 +8729,0 +8730,0 +8731,0 +8732,0 +8733,0 +8734,0 +8735,0 +8736,0 +8737,0 +8738,0 +8739,0 +8740,0 +8741,0 +8742,0 +8743,0 +8744,0 +8745,0 +8746,0 +8747,0 +8748,0 +8749,0 +8750,0 +8751,0 +8752,0 +8753,0 +8754,0 +8755,0 +8756,0 +8757,0 +8758,0 +8759,0 +8760,0 +8761,0 +8762,0 +8763,0 +8764,0 +8765,0 +8766,0 +8767,0 +8768,0 +8769,0 +8770,0 +8771,0 +8772,0 +8773,0 +8774,0 +8775,0 +8776,0 +8777,0 +8778,0 +8779,0 +8780,0 +8781,0 +8782,0 +8783,0 +8784,0 +8785,0 +8786,0 +8787,0 +8788,0 +8789,0 +8790,0 +8791,0 +8792,0 +8793,0 +8794,0 +8795,0 +8796,0 +8797,0 +8798,0 +8799,0 +8800,0 +8801,0 +8802,0 +8803,0 +8804,0 +8805,0 +8806,0 +8807,0 +8808,0 +8809,0 +8810,0 +8811,0 +8812,0 +8813,0 +8814,0 +8815,0 +8816,0 +8817,0 +8818,0 +8819,0 +8820,0 +8821,0 +8822,0 +8823,0 +8824,0 +8825,0 +8826,0 +8827,0 +8828,0 +8829,0 +8830,0 +8831,0 +8832,0 +8833,0 +8834,0 +8835,0 +8836,0 +8837,0 +8838,0 +8839,0 +8840,0 +8841,0 +8842,0 +8843,0 +8844,0 +8845,0 +8846,0 +8847,0 +8848,0 +8849,0 +8850,0 +8851,0 +8852,0 +8853,0 +8854,0 +8855,0 +8856,0 +8857,0 +8858,0 +8859,0 +8860,0 +8861,0 +8862,0 +8863,0 +8864,0 +8865,0 +8866,0 +8867,0 +8868,0 +8869,0 +8870,0 +8871,0 +8872,0 +8873,0 +8874,0 +8875,0 +8876,0 +8877,0 +8878,0 +8879,0 +8880,0 +8881,0 +8882,0 +8883,0 +8884,0 +8885,0 +8886,0 +8887,0 +8888,0 +8889,0 +8890,0 +8891,0 +8892,0 +8893,0 +8894,0 +8895,0 +8896,0 +8897,0 +8898,0 +8899,0 +8900,0 +8901,0 +8902,0 +8903,0 +8904,0 +8905,0 +8906,0 +8907,0 +8908,0 +8909,0 +8910,0 +8911,0 +8912,0 +8913,0 +8914,0 +8915,0 +8916,0 +8917,0 +8918,0 +8919,0 +8920,0 +8921,0 +8922,0 +8923,0 +8924,0 +8925,0 +8926,0 +8927,0 +8928,0 +8929,0 +8930,0 +8931,0 +8932,0 +8933,0 +8934,0 +8935,0 +8936,0 +8937,0 +8938,0 +8939,0 +8940,0 +8941,0 +8942,0 +8943,0 +8944,0 +8945,0 +8946,0 +8947,0 +8948,0 +8949,0 +8950,0 +8951,0 +8952,0 +8953,0 +8954,0 +8955,0 +8956,0 +8957,0 +8958,0 +8959,0 +8960,0 +8961,0 +8962,0 +8963,0 +8964,0 +8965,0 +8966,0 +8967,0 +8968,0 +8969,0 +8970,0 +8971,0 +8972,0 +8973,0 +8974,0 +8975,0 +8976,0 +8977,0 +8978,0 +8979,0 +8980,0 +8981,0 +8982,0 +8983,0 +8984,0 +8985,0 +8986,0 +8987,0 +8988,0 +8989,0 +8990,0 +8991,0 +8992,0 +8993,0 +8994,0 +8995,0 +8996,0 +8997,0 +8998,0 +8999,0 +9000,0 +9001,0 +9002,0 +9003,0 +9004,0 +9005,0 +9006,0 +9007,0 +9008,0 +9009,0 +9010,0 +9011,0 +9012,0 +9013,0 +9014,0 +9015,0 +9016,0 +9017,0 +9018,0 +9019,0 +9020,0 +9021,0 +9022,0 +9023,0 +9024,0 +9025,0 +9026,0 +9027,0 +9028,0 +9029,0 +9030,0 +9031,0 +9032,0 +9033,0 +9034,0 +9035,0 +9036,0 +9037,0 +9038,0 +9039,0 +9040,0 +9041,0 +9042,0 +9043,0 +9044,0 +9045,0 +9046,0 +9047,0 +9048,0 +9049,0 +9050,0 +9051,0 +9052,0 +9053,0 +9054,0 +9055,0 +9056,0 +9057,0 +9058,0 +9059,0 +9060,0 +9061,0 +9062,0 +9063,0 +9064,0 +9065,0 +9066,0 +9067,0 +9068,0 +9069,0 +9070,0 +9071,0 +9072,0 +9073,0 +9074,0 +9075,0 +9076,0 +9077,0 +9078,0 +9079,0 +9080,0 +9081,0 +9082,0 +9083,0 +9084,0 +9085,0 +9086,0 +9087,0 +9088,0 +9089,0 +9090,0 +9091,0 +9092,0 +9093,0 +9094,0 +9095,0 +9096,0 +9097,0 +9098,0 +9099,0 +9100,0 +9101,0 +9102,0 +9103,0 +9104,0 +9105,0 +9106,0 +9107,0 +9108,0 +9109,0 +9110,0 +9111,0 +9112,0 +9113,0 +9114,0 +9115,0 +9116,0 +9117,0 +9118,0 +9119,0 +9120,0 +9121,0 +9122,0 +9123,0 +9124,0 +9125,0 +9126,0 +9127,0 +9128,0 +9129,0 +9130,0 +9131,0 +9132,0 +9133,0 +9134,0 +9135,0 +9136,0 +9137,0 +9138,0 +9139,0 +9140,0 +9141,0 +9142,0 +9143,0 +9144,0 +9145,0 +9146,0 +9147,0 +9148,0 +9149,0 +9150,0 +9151,0 +9152,0 +9153,0 +9154,0 +9155,0 +9156,0 +9157,0 +9158,0 +9159,0 +9160,0 +9161,0 +9162,0 +9163,0 +9164,0 +9165,0 +9166,0 +9167,0 +9168,0 +9169,0 +9170,0 +9171,0 +9172,0 +9173,0 +9174,0 +9175,0 +9176,0 +9177,0 +9178,0 +9179,0 +9180,0 +9181,0 +9182,0 +9183,0 +9184,0 +9185,0 +9186,0 +9187,0 +9188,0 +9189,0 +9190,0 +9191,0 +9192,0 +9193,0 +9194,0 +9195,0 +9196,0 +9197,0 +9198,0 +9199,0 +9200,0 +9201,0 +9202,0 +9203,0 +9204,0 +9205,0 +9206,0 +9207,0 +9208,0 +9209,0 +9210,0 +9211,0 +9212,0 +9213,0 +9214,0 +9215,0 +9216,0 +9217,0 +9218,0 +9219,0 +9220,0 +9221,0 +9222,0 +9223,0 +9224,0 +9225,0 +9226,0 +9227,0 +9228,0 +9229,0 +9230,0 +9231,0 +9232,0 +9233,0 +9234,0 +9235,0 +9236,0 +9237,0 +9238,0 +9239,0 +9240,0 +9241,0 +9242,0 +9243,0 +9244,0 +9245,0 +9246,0 +9247,0 +9248,0 +9249,0 +9250,0 +9251,0 +9252,0 +9253,0 +9254,0 +9255,0 +9256,0 +9257,0 +9258,0 +9259,0 +9260,0 +9261,0 +9262,0 +9263,0 +9264,0 +9265,0 +9266,0 +9267,0 +9268,0 +9269,0 +9270,0 +9271,0 +9272,0 +9273,0 +9274,0 +9275,0 +9276,0 +9277,0 +9278,0 +9279,0 +9280,0 +9281,0 +9282,0 +9283,0 +9284,0 +9285,0 +9286,0 +9287,0 +9288,0 +9289,0 +9290,0 +9291,0 +9292,0 +9293,0 +9294,0 +9295,0 +9296,0 +9297,0 +9298,0 +9299,0 +9300,0 +9301,0 +9302,0 +9303,0 +9304,0 +9305,0 +9306,0 +9307,0 +9308,0 +9309,0 +9310,0 +9311,0 +9312,0 +9313,0 +9314,0 +9315,0 +9316,0 +9317,0 +9318,0 +9319,0 +9320,0 +9321,0 +9322,0 +9323,0 +9324,0 +9325,0 +9326,0 +9327,0 +9328,0 +9329,0 +9330,0 +9331,0 +9332,0 +9333,0 +9334,0 +9335,0 +9336,0 +9337,0 +9338,0 +9339,0 +9340,0 +9341,0 +9342,0 +9343,0 +9344,0 +9345,0 +9346,0 +9347,0 +9348,0 +9349,0 +9350,0 +9351,0 +9352,0 +9353,0 +9354,0 +9355,0 +9356,0 +9357,0 +9358,0 +9359,0 +9360,0 +9361,0 +9362,0 +9363,0 +9364,0 +9365,0 +9366,0 +9367,0 +9368,0 +9369,0 +9370,0 +9371,0 +9372,0 +9373,0 +9374,0 +9375,0 +9376,0 +9377,0 +9378,0 +9379,0 +9380,0 +9381,0 +9382,0 +9383,0 +9384,0 +9385,0 +9386,0 +9387,0 +9388,0 +9389,0 +9390,0 +9391,0 +9392,0 +9393,0 +9394,0 +9395,0 +9396,0 +9397,0 +9398,0 +9399,0 +9400,0 +9401,0 +9402,0 +9403,0 +9404,0 +9405,0 +9406,0 +9407,0 +9408,0 +9409,0 +9410,0 +9411,0 +9412,0 +9413,0 +9414,0 +9415,0 +9416,0 +9417,0 +9418,0 +9419,0 +9420,0 +9421,0 +9422,0 +9423,0 +9424,0 +9425,0 +9426,0 +9427,0 +9428,0 +9429,0 +9430,0 +9431,0 +9432,0 +9433,0 +9434,0 +9435,0 +9436,0 +9437,0 +9438,0 +9439,0 +9440,0 +9441,0 +9442,0 +9443,0 +9444,0 +9445,0 +9446,0 +9447,0 +9448,0 +9449,0 +9450,0 +9451,0 +9452,0 +9453,0 +9454,0 +9455,0 +9456,0 +9457,0 +9458,0 +9459,0 +9460,0 +9461,0 +9462,0 +9463,0 +9464,0 +9465,0 +9466,0 +9467,0 +9468,0 +9469,0 +9470,0 +9471,0 +9472,0 +9473,0 +9474,0 +9475,0 +9476,0 +9477,0 +9478,0 +9479,0 +9480,0 +9481,0 +9482,0 +9483,0 +9484,0 +9485,0 +9486,0 +9487,0 +9488,0 +9489,0 +9490,0 +9491,0 +9492,0 +9493,0 +9494,0 +9495,0 +9496,0 +9497,0 +9498,0 +9499,0 +9500,0 +9501,0 +9502,0 +9503,0 +9504,0 +9505,0 +9506,0 +9507,0 +9508,0 +9509,0 +9510,0 +9511,0 +9512,0 +9513,0 +9514,0 +9515,0 +9516,0 +9517,0 +9518,0 +9519,0 +9520,0 +9521,0 +9522,0 +9523,0 +9524,0 +9525,0 +9526,0 +9527,0 +9528,0 +9529,0 +9530,0 +9531,0 +9532,0 +9533,0 +9534,0 +9535,0 +9536,0 +9537,0 +9538,0 +9539,0 +9540,0 +9541,0 +9542,0 +9543,0 +9544,0 +9545,0 +9546,0 +9547,0 +9548,0 +9549,0 +9550,0 +9551,0 +9552,0 +9553,0 +9554,0 +9555,0 +9556,0 +9557,0 +9558,0 +9559,0 +9560,0 +9561,0 +9562,0 +9563,0 +9564,0 +9565,0 +9566,0 +9567,0 +9568,0 +9569,0 +9570,0 +9571,0 +9572,0 +9573,0 +9574,0 +9575,0 +9576,0 +9577,0 +9578,0 +9579,0 +9580,0 +9581,0 +9582,0 +9583,0 +9584,0 +9585,0 +9586,0 +9587,0 +9588,0 +9589,0 +9590,0 +9591,0 +9592,0 +9593,0 +9594,0 +9595,0 +9596,0 +9597,0 +9598,0 +9599,0 +9600,0 +9601,0 +9602,0 +9603,0 +9604,0 +9605,0 +9606,0 +9607,0 +9608,0 +9609,0 +9610,0 +9611,0 +9612,0 +9613,0 +9614,0 +9615,0 +9616,0 +9617,0 +9618,0 +9619,0 +9620,0 +9621,0 +9622,0 +9623,0 +9624,0 +9625,0 +9626,0 +9627,0 +9628,0 +9629,0 +9630,0 +9631,0 +9632,0 +9633,0 +9634,0 +9635,0 +9636,0 +9637,0 +9638,0 +9639,0 +9640,0 +9641,0 +9642,0 +9643,0 +9644,0 +9645,0 +9646,0 +9647,0 +9648,0 +9649,0 +9650,0 +9651,0 +9652,0 +9653,0 +9654,0 +9655,0 +9656,0 +9657,0 +9658,0 +9659,0 +9660,0 +9661,0 +9662,0 +9663,0 +9664,0 +9665,0 +9666,0 +9667,0 +9668,0 +9669,0 +9670,0 +9671,0 +9672,0 +9673,0 +9674,0 +9675,0 +9676,0 +9677,0 +9678,0 +9679,0 +9680,0 +9681,0 +9682,0 +9683,0 +9684,0 +9685,0 +9686,0 +9687,0 +9688,0 +9689,0 +9690,0 +9691,0 +9692,0 +9693,0 +9694,0 +9695,0 +9696,0 +9697,0 +9698,0 +9699,0 +9700,0 +9701,0 +9702,0 +9703,0 +9704,0 +9705,0 +9706,0 +9707,0 +9708,0 +9709,0 +9710,0 +9711,0 +9712,0 +9713,0 +9714,0 +9715,0 +9716,0 +9717,0 +9718,0 +9719,0 +9720,0 +9721,0 +9722,0 +9723,0 +9724,0 +9725,0 +9726,0 +9727,0 +9728,0 +9729,0 +9730,0 +9731,0 +9732,0 +9733,0 +9734,0 +9735,0 +9736,0 +9737,0 +9738,0 +9739,0 +9740,0 +9741,0 +9742,0 +9743,0 +9744,0 +9745,0 +9746,0 +9747,0 +9748,0 +9749,0 +9750,0 +9751,0 +9752,0 +9753,0 +9754,0 +9755,0 +9756,0 +9757,0 +9758,0 +9759,0 +9760,0 +9761,0 +9762,0 +9763,0 +9764,0 +9765,0 +9766,0 +9767,0 +9768,0 +9769,0 +9770,0 +9771,0 +9772,0 +9773,0 +9774,0 +9775,0 +9776,0 +9777,0 +9778,0 +9779,0 +9780,0 +9781,0 +9782,0 +9783,0 +9784,0 +9785,0 +9786,0 +9787,0 +9788,0 +9789,0 +9790,0 +9791,0 +9792,0 +9793,0 +9794,0 +9795,0 +9796,0 +9797,0 +9798,0 +9799,0 +9800,0 +9801,0 +9802,0 +9803,0 +9804,0 +9805,0 +9806,0 +9807,0 +9808,0 +9809,0 +9810,0 +9811,0 +9812,0 +9813,0 +9814,0 +9815,0 +9816,0 +9817,0 +9818,0 +9819,0 +9820,0 +9821,0 +9822,0 +9823,0 +9824,0 +9825,0 +9826,0 +9827,0 +9828,0 +9829,0 +9830,0 +9831,0 +9832,0 +9833,0 +9834,0 +9835,0 +9836,0 +9837,0 +9838,0 +9839,0 +9840,0 +9841,0 +9842,0 +9843,0 +9844,0 +9845,0 +9846,0 +9847,0 +9848,0 +9849,0 +9850,0 +9851,0 +9852,0 +9853,0 +9854,0 +9855,0 +9856,0 +9857,0 +9858,0 +9859,0 +9860,0 +9861,0 +9862,0 +9863,0 +9864,0 +9865,0 +9866,0 +9867,0 +9868,0 +9869,0 +9870,0 +9871,0 +9872,0 +9873,0 +9874,0 +9875,0 +9876,0 +9877,0 +9878,0 +9879,0 +9880,0 +9881,0 +9882,0 +9883,0 +9884,0 +9885,0 +9886,0 +9887,0 +9888,0 +9889,0 +9890,0 +9891,0 +9892,0 +9893,0 +9894,0 +9895,0 +9896,0 +9897,0 +9898,0 +9899,0 +9900,0 +9901,0 +9902,0 +9903,0 +9904,0 +9905,0 +9906,0 +9907,0 +9908,0 +9909,0 +9910,0 +9911,0 +9912,0 +9913,0 +9914,0 +9915,0 +9916,0 +9917,0 +9918,0 +9919,0 +9920,0 +9921,0 +9922,0 +9923,0 +9924,0 +9925,0 +9926,0 +9927,0 +9928,0 +9929,0 +9930,0 +9931,0 +9932,0 +9933,0 +9934,0 +9935,0 +9936,0 +9937,0 +9938,0 +9939,0 +9940,0 +9941,0 +9942,0 +9943,0 +9944,0 +9945,0 +9946,0 +9947,0 +9948,0 +9949,0 +9950,0 +9951,0 +9952,0 +9953,0 +9954,0 +9955,0 +9956,0 +9957,0 +9958,0 +9959,0 +9960,0 +9961,0 +9962,0 +9963,0 +9964,0 +9965,0 +9966,0 +9967,0 +9968,0 +9969,0 +9970,0 +9971,0 +9972,0 +9973,0 +9974,0 +9975,0 +9976,0 +9977,0 +9978,0 +9979,0 +9980,0 +9981,0 +9982,0 +9983,0 +9984,0 +9985,0 +9986,0 +9987,0 +9988,0 +9989,0 +9990,0 +9991,0 +9992,0 +9993,0 +9994,0 +9995,0 +9996,0 +9997,0 +9998,0 +9999,0 +10000,0 +10001,0 +10002,0 +10003,0 +10004,0 +10005,0 +10006,0 +10007,0 +10008,0 +10009,0 +10010,0 +10011,0 +10012,0 +10013,0 +10014,0 +10015,0 +10016,0 +10017,0 +10018,0 +10019,0 +10020,0 +10021,0 +10022,0 +10023,0 +10024,0 +10025,0 +10026,0 +10027,0 +10028,0 +10029,0 +10030,0 +10031,0 +10032,0 +10033,0 +10034,0 +10035,0 +10036,0 +10037,0 +10038,0 +10039,0 +10040,0 +10041,0 +10042,0 +10043,0 +10044,0 +10045,0 +10046,0 +10047,0 +10048,0 +10049,0 +10050,0 +10051,0 +10052,0 +10053,0 +10054,0 +10055,0 +10056,0 +10057,0 +10058,0 +10059,0 +10060,0 +10061,0 +10062,0 +10063,0 +10064,0 +10065,0 +10066,0 +10067,0 +10068,0 +10069,0 +10070,0 +10071,0 +10072,0 +10073,0 +10074,0 +10075,0 +10076,0 +10077,0 +10078,0 +10079,0 +10080,0 +10081,0 +10082,0 +10083,0 +10084,0 +10085,0 +10086,0 +10087,0 +10088,0 +10089,0 +10090,0 +10091,0 +10092,0 +10093,0 +10094,0 +10095,0 +10096,0 +10097,0 +10098,0 +10099,0 +10100,0 +10101,0 +10102,0 +10103,0 +10104,0 +10105,0 +10106,0 +10107,0 +10108,0 +10109,0 +10110,0 +10111,0 +10112,0 +10113,0 +10114,0 +10115,0 +10116,0 +10117,0 +10118,0 +10119,0 +10120,0 +10121,0 +10122,0 +10123,0 +10124,0 +10125,0 +10126,0 +10127,0 +10128,0 +10129,0 +10130,0 +10131,0 +10132,0 +10133,0 +10134,0 +10135,0 +10136,0 +10137,0 +10138,0 +10139,0 +10140,0 +10141,0 +10142,0 +10143,0 +10144,0 +10145,0 +10146,0 +10147,0 +10148,0 +10149,0 +10150,0 +10151,0 +10152,0 +10153,0 +10154,0 +10155,0 +10156,0 +10157,0 +10158,0 +10159,0 +10160,0 +10161,0 +10162,0 +10163,0 +10164,0 +10165,0 +10166,0 +10167,0 +10168,0 +10169,0 +10170,0 +10171,0 +10172,0 +10173,0 +10174,0 +10175,0 +10176,0 +10177,0 +10178,0 +10179,0 +10180,0 +10181,0 +10182,0 +10183,0 +10184,0 +10185,0 +10186,0 +10187,0 +10188,0 +10189,0 +10190,0 +10191,0 +10192,0 +10193,0 +10194,0 +10195,0 +10196,0 +10197,0 +10198,0 +10199,0 +10200,0 +10201,0 +10202,0 +10203,0 +10204,0 +10205,0 +10206,0 +10207,0 +10208,0 +10209,0 +10210,0 +10211,0 +10212,0 +10213,0 +10214,0 +10215,0 +10216,0 +10217,0 +10218,0 +10219,0 +10220,0 +10221,0 +10222,0 +10223,0 +10224,0 +10225,0 +10226,0 +10227,0 +10228,0 +10229,0 +10230,0 +10231,0 +10232,0 +10233,0 +10234,0 +10235,0 +10236,0 +10237,0 +10238,0 +10239,0 +10240,0 +10241,0 +10242,0 +10243,0 +10244,0 +10245,0 +10246,0 +10247,0 +10248,0 +10249,0 +10250,0 +10251,0 +10252,0 +10253,0 +10254,0 +10255,0 +10256,0 +10257,0 +10258,0 +10259,0 +10260,0 +10261,0 +10262,0 +10263,0 +10264,0 +10265,0 +10266,0 +10267,0 +10268,0 +10269,0 +10270,0 +10271,0 +10272,0 +10273,0 +10274,0 +10275,0 +10276,0 +10277,0 +10278,0 +10279,0 +10280,0 +10281,0 +10282,0 +10283,0 +10284,0 +10285,0 +10286,0 +10287,0 +10288,0 +10289,0 +10290,0 +10291,0 +10292,0 +10293,0 +10294,0 +10295,0 +10296,0 +10297,0 +10298,0 +10299,0 +10300,0 +10301,0 +10302,0 +10303,0 +10304,0 +10305,0 +10306,0 +10307,0 +10308,0 +10309,0 +10310,0 +10311,0 +10312,0 +10313,0 +10314,0 +10315,0 +10316,0 +10317,0 +10318,0 +10319,0 +10320,0 +10321,0 +10322,0 +10323,0 +10324,0 +10325,0 +10326,0 +10327,0 +10328,0 +10329,0 +10330,0 +10331,0 +10332,0 +10333,0 +10334,0 +10335,0 +10336,0 +10337,0 +10338,0 +10339,0 +10340,0 +10341,0 +10342,0 +10343,0 +10344,0 +10345,0 +10346,0 +10347,0 +10348,0 +10349,0 +10350,0 +10351,0 +10352,0 +10353,0 +10354,0 +10355,0 +10356,0 +10357,0 +10358,0 +10359,0 +10360,0 +10361,0 +10362,0 +10363,0 +10364,0 +10365,0 +10366,0 +10367,0 +10368,0 +10369,0 +10370,0 +10371,0 +10372,0 +10373,0 +10374,0 +10375,0 +10376,0 +10377,0 +10378,0 +10379,0 +10380,0 +10381,0 +10382,0 +10383,0 +10384,0 +10385,0 +10386,0 +10387,0 +10388,0 +10389,0 +10390,0 +10391,0 +10392,0 +10393,0 +10394,0 +10395,0 +10396,0 +10397,0 +10398,0 +10399,0 +10400,0 +10401,0 +10402,0 +10403,0 +10404,0 +10405,0 +10406,0 +10407,0 +10408,0 +10409,0 +10410,0 +10411,0 +10412,0 +10413,0 +10414,0 +10415,0 +10416,0 +10417,0 +10418,0 +10419,0 +10420,0 +10421,0 +10422,0 +10423,0 +10424,0 +10425,0 +10426,0 +10427,0 +10428,0 +10429,0 +10430,0 +10431,0 +10432,0 +10433,0 +10434,0 +10435,0 +10436,0 +10437,0 +10438,0 +10439,0 +10440,0 +10441,0 +10442,0 +10443,0 +10444,0 +10445,0 +10446,0 +10447,0 +10448,0 +10449,0 +10450,0 +10451,0 +10452,0 +10453,0 +10454,0 +10455,0 +10456,0 +10457,0 +10458,0 +10459,0 +10460,0 +10461,0 +10462,0 +10463,0 +10464,0 +10465,0 +10466,0 +10467,0 +10468,0 +10469,0 +10470,0 +10471,0 +10472,0 +10473,0 +10474,0 +10475,0 +10476,0 +10477,0 +10478,0 +10479,0 +10480,0 +10481,0 +10482,0 +10483,0 +10484,0 +10485,0 +10486,0 +10487,0 +10488,0 +10489,0 +10490,0 +10491,0 +10492,0 +10493,0 +10494,0 +10495,0 +10496,0 +10497,0 +10498,0 +10499,0 +10500,0 +10501,0 +10502,0 +10503,0 +10504,0 +10505,0 +10506,0 +10507,0 +10508,0 +10509,0 +10510,0 +10511,0 +10512,0 +10513,0 +10514,0 +10515,0 +10516,0 +10517,0 +10518,0 +10519,0 +10520,0 +10521,0 +10522,0 +10523,0 +10524,0 +10525,0 +10526,0 +10527,0 +10528,0 +10529,0 +10530,0 +10531,0 +10532,0 +10533,0 +10534,0 +10535,0 +10536,0 +10537,0 +10538,0 +10539,0 +10540,0 +10541,0 +10542,0 +10543,0 +10544,0 +10545,0 +10546,0 +10547,0 +10548,0 +10549,0 +10550,0 +10551,0 +10552,0 +10553,0 +10554,0 +10555,0 +10556,0 +10557,0 +10558,0 +10559,0 +10560,0 +10561,0 +10562,0 +10563,0 +10564,0 +10565,0 +10566,0 +10567,0 +10568,0 +10569,0 +10570,0 +10571,0 +10572,0 +10573,0 +10574,0 +10575,0 +10576,0 +10577,0 +10578,0 +10579,0 +10580,0 +10581,0 +10582,0 +10583,0 +10584,0 +10585,0 +10586,0 +10587,0 +10588,0 +10589,0 +10590,0 +10591,0 +10592,0 +10593,0 +10594,0 +10595,0 +10596,0 +10597,0 +10598,0 +10599,0 +10600,0 +10601,0 +10602,0 +10603,0 +10604,0 +10605,0 +10606,0 +10607,0 +10608,0 +10609,0 +10610,0 +10611,0 +10612,0 +10613,0 +10614,0 +10615,0 +10616,0 +10617,0 +10618,0 +10619,0 +10620,0 +10621,0 +10622,0 +10623,0 +10624,0 +10625,0 +10626,0 +10627,0 +10628,0 +10629,0 +10630,0 +10631,0 +10632,0 +10633,0 +10634,0 +10635,0 +10636,0 +10637,0 +10638,0 +10639,0 +10640,0 +10641,0 +10642,0 +10643,0 +10644,0 +10645,0 +10646,0 +10647,0 +10648,0 +10649,0 +10650,0 +10651,0 +10652,0 +10653,0 +10654,0 +10655,0 +10656,0 +10657,0 +10658,0 +10659,0 +10660,0 +10661,0 +10662,0 +10663,0 +10664,0 +10665,0 +10666,0 +10667,0 +10668,0 +10669,0 +10670,0 +10671,0 +10672,0 +10673,0 +10674,0 +10675,0 +10676,0 +10677,0 +10678,0 +10679,0 +10680,0 +10681,0 +10682,0 +10683,0 +10684,0 +10685,0 +10686,0 +10687,0 +10688,0 +10689,0 +10690,0 +10691,0 +10692,0 +10693,0 +10694,0 +10695,0 +10696,0 +10697,0 +10698,0 +10699,0 +10700,0 +10701,0 +10702,0 +10703,0 +10704,0 +10705,0 +10706,0 +10707,0 +10708,0 +10709,0 +10710,0 +10711,0 +10712,0 +10713,0 +10714,0 +10715,0 +10716,0 +10717,0 +10718,0 +10719,0 +10720,0 +10721,0 +10722,0 +10723,0 +10724,0 +10725,0 +10726,0 +10727,0 +10728,0 +10729,0 +10730,0 +10731,0 +10732,0 +10733,0 +10734,0 +10735,0 +10736,0 +10737,0 +10738,0 +10739,0 +10740,0 +10741,0 +10742,0 +10743,0 +10744,0 +10745,0 +10746,0 +10747,0 +10748,0 +10749,0 +10750,0 +10751,0 +10752,0 +10753,0 +10754,0 +10755,0 +10756,0 +10757,0 +10758,0 +10759,0 +10760,0 +10761,0 +10762,0 +10763,0 +10764,0 +10765,0 +10766,0 +10767,0 +10768,0 +10769,0 +10770,0 +10771,0 +10772,0 +10773,0 +10774,0 +10775,0 +10776,0 +10777,0 +10778,0 +10779,0 +10780,0 +10781,0 +10782,0 +10783,0 +10784,0 +10785,0 +10786,0 +10787,0 +10788,0 +10789,0 +10790,0 +10791,0 +10792,0 +10793,0 +10794,0 +10795,0 +10796,0 +10797,0 +10798,0 +10799,0 +10800,0 +10801,0 +10802,0 +10803,0 +10804,0 +10805,0 +10806,0 +10807,0 +10808,0 +10809,0 +10810,0 +10811,0 +10812,0 +10813,0 +10814,0 +10815,0 +10816,0 +10817,0 +10818,0 +10819,0 +10820,0 +10821,0 +10822,0 +10823,0 +10824,0 +10825,0 +10826,0 +10827,0 +10828,0 +10829,0 +10830,0 +10831,0 +10832,0 +10833,0 +10834,0 +10835,0 +10836,0 +10837,0 +10838,0 +10839,0 +10840,0 +10841,0 +10842,0 +10843,0 +10844,0 +10845,0 +10846,0 +10847,0 +10848,0 +10849,0 +10850,0 +10851,0 +10852,0 +10853,0 +10854,0 +10855,0 +10856,0 +10857,0 +10858,0 +10859,0 +10860,0 +10861,0 +10862,0 +10863,0 +10864,0 +10865,0 +10866,0 +10867,0 +10868,0 +10869,0 +10870,0 +10871,0 +10872,0 +10873,0 +10874,0 +10875,0 +10876,0 +10877,0 +10878,0 +10879,0 +10880,0 +10881,0 +10882,0 +10883,0 +10884,0 +10885,0 +10886,0 +10887,0 +10888,0 +10889,0 +10890,0 +10891,0 +10892,0 +10893,0 +10894,0 +10895,0 +10896,0 +10897,0 +10898,0 +10899,0 +10900,0 +10901,0 +10902,0 +10903,0 +10904,0 +10905,0 +10906,0 +10907,0 +10908,0 +10909,0 +10910,0 +10911,0 +10912,0 +10913,0 +10914,0 +10915,0 +10916,0 +10917,0 +10918,0 +10919,0 +10920,0 +10921,0 +10922,0 +10923,0 +10924,0 +10925,0 +10926,0 +10927,0 +10928,0 +10929,0 +10930,0 +10931,0 +10932,0 +10933,0 +10934,0 +10935,0 +10936,0 +10937,0 +10938,0 +10939,0 +10940,0 +10941,0 +10942,0 +10943,0 +10944,0 +10945,0 +10946,0 +10947,0 +10948,0 +10949,0 +10950,0 +10951,0 +10952,0 +10953,0 +10954,0 +10955,0 +10956,0 +10957,0 +10958,0 +10959,0 +10960,0 +10961,0 +10962,0 +10963,0 +10964,0 +10965,0 +10966,0 +10967,0 +10968,0 +10969,0 +10970,0 +10971,0 +10972,0 +10973,0 +10974,0 +10975,0 +10976,0 +10977,0 +10978,0 +10979,0 +10980,0 +10981,0 +10982,0 +10983,0 +10984,0 +10985,0 +10986,0 +10987,0 +10988,0 +10989,0 +10990,0 +10991,0 +10992,0 +10993,0 +10994,0 +10995,0 +10996,0 +10997,0 +10998,0 +10999,0 +11000,0 +11001,0 +11002,0 +11003,0 +11004,0 +11005,0 +11006,0 +11007,0 +11008,0 +11009,0 +11010,0 +11011,0 +11012,0 +11013,0 +11014,0 +11015,0 +11016,0 +11017,0 +11018,0 +11019,0 +11020,0 +11021,0 +11022,0 +11023,0 +11024,0 +11025,0 +11026,0 +11027,0 +11028,0 +11029,0 +11030,0 +11031,0 +11032,0 +11033,0 +11034,0 +11035,0 +11036,0 +11037,0 +11038,0 +11039,0 +11040,0 +11041,0 +11042,0 +11043,0 +11044,0 +11045,0 +11046,0 +11047,0 +11048,0 +11049,0 +11050,0 +11051,0 +11052,0 +11053,0 +11054,0 +11055,0 +11056,0 +11057,0 +11058,0 +11059,0 +11060,0 +11061,0 +11062,0 +11063,0 +11064,0 +11065,0 +11066,0 +11067,0 +11068,0 +11069,0 +11070,0 +11071,0 +11072,0 +11073,0 +11074,0 +11075,0 +11076,0 +11077,0 +11078,0 +11079,0 +11080,0 +11081,0 +11082,0 +11083,0 +11084,0 +11085,0 +11086,0 +11087,0 +11088,0 +11089,0 +11090,0 +11091,0 +11092,0 +11093,0 +11094,0 +11095,0 +11096,0 +11097,0 +11098,0 +11099,0 +11100,0 +11101,0 +11102,0 +11103,0 +11104,0 +11105,0 +11106,0 +11107,0 +11108,0 +11109,0 +11110,0 +11111,0 +11112,0 +11113,0 +11114,0 +11115,0 +11116,0 +11117,0 +11118,0 +11119,0 +11120,0 +11121,0 +11122,0 +11123,0 +11124,0 +11125,0 +11126,0 +11127,0 +11128,0 +11129,0 +11130,0 +11131,0 +11132,0 +11133,0 +11134,0 +11135,0 +11136,0 +11137,0 +11138,0 +11139,0 +11140,0 +11141,0 +11142,0 +11143,0 +11144,0 +11145,0 +11146,0 +11147,0 +11148,0 +11149,0 +11150,0 +11151,0 +11152,0 +11153,0 +11154,0 +11155,0 +11156,0 +11157,0 +11158,0 +11159,0 +11160,0 +11161,0 +11162,0 +11163,0 +11164,0 +11165,0 +11166,0 +11167,0 +11168,0 +11169,0 +11170,0 +11171,0 +11172,0 +11173,0 +11174,0 +11175,0 +11176,0 +11177,0 +11178,0 +11179,0 +11180,0 +11181,0 +11182,0 +11183,0 +11184,0 +11185,0 +11186,0 +11187,0 +11188,0 +11189,0 +11190,0 +11191,0 +11192,0 +11193,0 +11194,0 +11195,0 +11196,0 +11197,0 +11198,0 +11199,0 +11200,0 +11201,0 +11202,0 +11203,0 +11204,0 +11205,0 +11206,0 +11207,0 +11208,0 +11209,0 +11210,0 +11211,0 +11212,0 +11213,0 +11214,0 +11215,0 +11216,0 +11217,0 +11218,0 +11219,0 +11220,0 +11221,0 +11222,0 +11223,0 +11224,0 +11225,0 +11226,0 +11227,0 +11228,0 +11229,0 +11230,0 +11231,0 +11232,0 +11233,0 +11234,0 +11235,0 +11236,0 +11237,0 +11238,0 +11239,0 +11240,0 +11241,0 +11242,0 +11243,0 +11244,0 +11245,0 +11246,0 +11247,0 +11248,0 +11249,0 +11250,0 +11251,0 +11252,0 +11253,0 +11254,0 +11255,0 +11256,0 +11257,0 +11258,0 +11259,0 +11260,0 +11261,0 +11262,0 +11263,0 +11264,0 +11265,0 +11266,0 +11267,0 +11268,0 +11269,0 +11270,0 +11271,0 +11272,0 +11273,0 +11274,0 +11275,0 +11276,0 +11277,0 +11278,0 +11279,0 +11280,0 +11281,0 +11282,0 +11283,0 +11284,0 +11285,0 +11286,0 +11287,0 +11288,0 +11289,0 +11290,0 +11291,0 +11292,0 +11293,0 +11294,0 +11295,0 +11296,0 +11297,0 +11298,0 +11299,0 +11300,0 +11301,0 +11302,0 +11303,0 +11304,0 +11305,0 +11306,0 +11307,0 +11308,0 +11309,0 +11310,0 +11311,0 +11312,0 +11313,0 +11314,0 +11315,0 +11316,0 +11317,0 +11318,0 +11319,0 +11320,0 +11321,0 +11322,0 +11323,0 +11324,0 +11325,0 +11326,0 +11327,0 +11328,0 +11329,0 +11330,0 +11331,0 +11332,0 +11333,0 +11334,0 +11335,0 +11336,0 +11337,0 +11338,0 +11339,0 +11340,0 +11341,0 +11342,0 +11343,0 +11344,0 +11345,0 +11346,0 +11347,0 +11348,0 +11349,0 +11350,0 +11351,0 +11352,0 +11353,0 +11354,0 +11355,0 +11356,0 +11357,0 +11358,0 +11359,0 +11360,0 +11361,0 +11362,0 +11363,0 +11364,0 +11365,0 +11366,0 +11367,0 +11368,0 +11369,0 +11370,0 +11371,0 +11372,0 +11373,0 +11374,0 +11375,0 +11376,0 +11377,0 +11378,0 +11379,0 +11380,0 +11381,0 +11382,0 +11383,0 +11384,0 +11385,0 +11386,0 +11387,0 +11388,0 +11389,0 +11390,0 +11391,0 +11392,0 +11393,0 +11394,0 +11395,0 +11396,0 +11397,0 +11398,0 +11399,0 +11400,0 +11401,0 +11402,0 +11403,0 +11404,0 +11405,0 +11406,0 +11407,0 +11408,0 +11409,0 +11410,0 +11411,0 +11412,0 +11413,0 +11414,0 +11415,0 +11416,0 +11417,0 +11418,0 +11419,0 +11420,0 +11421,0 +11422,0 +11423,0 +11424,0 +11425,0 +11426,0 +11427,0 +11428,0 +11429,0 +11430,0 +11431,0 +11432,0 +11433,0 +11434,0 +11435,0 +11436,0 +11437,0 +11438,0 +11439,0 +11440,0 +11441,0 +11442,0 +11443,0 +11444,0 +11445,0 +11446,0 +11447,0 +11448,0 +11449,0 +11450,0 +11451,0 +11452,0 +11453,0 +11454,0 +11455,0 +11456,0 +11457,0 +11458,0 +11459,0 +11460,0 +11461,0 +11462,0 +11463,0 +11464,0 +11465,0 +11466,0 +11467,0 +11468,0 +11469,0 +11470,0 +11471,0 +11472,0 +11473,0 +11474,0 +11475,0 +11476,0 +11477,0 +11478,0 +11479,0 +11480,0 +11481,0 +11482,0 +11483,0 +11484,0 +11485,0 +11486,0 +11487,0 +11488,0 +11489,0 +11490,0 +11491,0 +11492,0 +11493,0 +11494,0 +11495,0 +11496,0 +11497,0 +11498,0 +11499,0 +11500,0 +11501,0 +11502,0 +11503,0 +11504,0 +11505,0 +11506,0 +11507,0 +11508,0 +11509,0 +11510,0 +11511,0 +11512,0 +11513,0 +11514,0 +11515,0 +11516,0 +11517,0 +11518,0 +11519,0 +11520,0 +11521,0 +11522,0 +11523,0 +11524,0 +11525,0 +11526,0 +11527,0 +11528,0 +11529,0 +11530,0 +11531,0 +11532,0 +11533,0 +11534,0 +11535,0 +11536,0 +11537,0 +11538,0 +11539,0 +11540,0 +11541,0 +11542,0 +11543,0 +11544,0 +11545,0 +11546,0 +11547,0 +11548,0 +11549,0 +11550,0 +11551,0 +11552,0 +11553,0 +11554,0 +11555,0 +11556,0 +11557,0 +11558,0 +11559,0 +11560,0 +11561,0 +11562,0 +11563,0 +11564,0 +11565,0 +11566,0 +11567,0 +11568,0 +11569,0 +11570,0 +11571,0 +11572,0 +11573,0 +11574,0 +11575,0 +11576,0 +11577,0 +11578,0 +11579,0 +11580,0 +11581,0 +11582,0 +11583,0 +11584,0 +11585,0 +11586,0 +11587,0 +11588,0 +11589,0 +11590,0 +11591,0 +11592,0 +11593,0 +11594,0 +11595,0 +11596,0 +11597,0 +11598,0 +11599,0 +11600,0 +11601,0 +11602,0 +11603,0 +11604,0 +11605,0 +11606,0 +11607,0 +11608,0 +11609,0 +11610,0 +11611,0 +11612,0 +11613,0 +11614,0 +11615,0 +11616,0 +11617,0 +11618,0 +11619,0 +11620,0 +11621,0 +11622,0 +11623,0 +11624,0 +11625,0 +11626,0 +11627,0 +11628,0 +11629,0 +11630,0 +11631,0 +11632,0 +11633,0 +11634,0 +11635,0 +11636,0 +11637,0 +11638,0 +11639,0 +11640,0 +11641,0 +11642,0 +11643,0 +11644,0 +11645,0 +11646,0 +11647,0 +11648,0 +11649,0 +11650,0 +11651,0 +11652,0 +11653,0 +11654,0 +11655,0 +11656,0 +11657,0 +11658,0 +11659,0 +11660,0 +11661,0 +11662,0 +11663,0 +11664,0 +11665,0 +11666,0 +11667,0 +11668,0 +11669,0 +11670,0 +11671,0 +11672,0 +11673,0 +11674,0 +11675,0 +11676,0 +11677,0 +11678,0 +11679,0 +11680,0 +11681,0 +11682,0 +11683,0 +11684,0 +11685,0 +11686,0 +11687,0 +11688,0 +11689,0 +11690,0 +11691,0 +11692,0 +11693,0 +11694,0 +11695,0 +11696,0 +11697,0 +11698,0 +11699,0 +11700,0 +11701,0 +11702,0 +11703,0 +11704,0 +11705,0 +11706,0 +11707,0 +11708,0 +11709,0 +11710,0 +11711,0 +11712,0 +11713,0 +11714,0 +11715,0 +11716,0 +11717,0 +11718,0 +11719,0 +11720,0 +11721,0 +11722,0 +11723,0 +11724,0 +11725,0 +11726,0 +11727,0 +11728,0 +11729,0 +11730,0 +11731,0 +11732,0 +11733,0 +11734,0 +11735,0 +11736,0 +11737,0 +11738,0 +11739,0 +11740,0 +11741,0 +11742,0 +11743,0 +11744,0 +11745,0 +11746,0 +11747,0 +11748,0 +11749,0 +11750,0 +11751,0 +11752,0 +11753,0 +11754,0 +11755,0 +11756,0 +11757,0 +11758,0 +11759,0 +11760,0 +11761,0 +11762,0 +11763,0 +11764,0 +11765,0 +11766,0 +11767,0 +11768,0 +11769,0 +11770,0 +11771,0 +11772,0 +11773,0 +11774,0 +11775,0 +11776,0 +11777,0 +11778,0 +11779,0 +11780,0 +11781,0 +11782,0 +11783,0 +11784,0 +11785,0 +11786,0 +11787,0 +11788,0 +11789,0 +11790,0 +11791,0 +11792,0 +11793,0 +11794,0 +11795,0 +11796,0 +11797,0 +11798,0 +11799,0 +11800,0 +11801,0 +11802,0 +11803,0 +11804,0 +11805,0 +11806,0 +11807,0 +11808,0 +11809,0 +11810,0 +11811,0 +11812,0 +11813,0 +11814,0 +11815,0 +11816,0 +11817,0 +11818,0 +11819,0 +11820,0 +11821,0 +11822,0 +11823,0 +11824,0 +11825,0 +11826,0 +11827,0 +11828,0 +11829,0 +11830,0 +11831,0 +11832,0 +11833,0 +11834,0 +11835,0 +11836,0 +11837,0 +11838,0 +11839,0 +11840,0 +11841,0 +11842,0 +11843,0 +11844,0 +11845,0 +11846,0 +11847,0 +11848,0 +11849,0 +11850,0 +11851,0 +11852,0 +11853,0 +11854,0 +11855,0 +11856,0 +11857,0 +11858,0 +11859,0 +11860,0 +11861,0 +11862,0 +11863,0 +11864,0 +11865,0 +11866,0 +11867,0 +11868,0 +11869,0 +11870,0 +11871,0 +11872,0 +11873,0 +11874,0 +11875,0 +11876,0 +11877,0 +11878,0 +11879,0 +11880,0 +11881,0 +11882,0 +11883,0 +11884,0 +11885,0 +11886,0 +11887,0 +11888,0 +11889,0 +11890,0 +11891,0 +11892,0 +11893,0 +11894,0 +11895,0 +11896,0 +11897,0 +11898,0 +11899,0 +11900,0 +11901,0 +11902,0 +11903,0 +11904,0 +11905,0 +11906,0 +11907,0 +11908,0 +11909,0 +11910,0 +11911,0 +11912,0 +11913,0 +11914,0 +11915,0 +11916,0 +11917,0 +11918,0 +11919,0 +11920,0 +11921,0 +11922,0 +11923,0 +11924,0 +11925,0 +11926,0 +11927,0 +11928,0 +11929,0 +11930,0 +11931,0 +11932,0 +11933,0 +11934,0 +11935,0 +11936,0 +11937,0 +11938,0 +11939,0 +11940,0 +11941,0 +11942,0 +11943,0 +11944,0 +11945,0 +11946,0 +11947,0 +11948,0 +11949,0 +11950,0 +11951,0 +11952,0 +11953,0 +11954,0 +11955,0 +11956,0 +11957,0 +11958,0 +11959,0 +11960,0 +11961,0 +11962,0 +11963,0 +11964,0 +11965,0 +11966,0 +11967,0 +11968,0 +11969,0 +11970,0 +11971,0 +11972,0 +11973,0 +11974,0 +11975,0 +11976,0 +11977,0 +11978,0 +11979,0 +11980,0 +11981,0 +11982,0 +11983,0 +11984,0 +11985,0 +11986,0 +11987,0 +11988,0 +11989,0 +11990,0 +11991,0 +11992,0 +11993,0 +11994,0 +11995,0 +11996,0 +11997,0 +11998,0 +11999,0 +12000,0 +12001,0 +12002,0 +12003,0 +12004,0 +12005,0 +12006,0 +12007,0 +12008,0 +12009,0 +12010,0 +12011,0 +12012,0 +12013,0 +12014,0 +12015,0 +12016,0 +12017,0 +12018,0 +12019,0 +12020,0 +12021,0 +12022,0 +12023,0 +12024,0 +12025,0 +12026,0 +12027,0 +12028,0 +12029,0 +12030,0 +12031,0 +12032,0 +12033,0 +12034,0 +12035,0 +12036,0 +12037,0 +12038,0 +12039,0 +12040,0 +12041,0 +12042,0 +12043,0 +12044,0 +12045,0 +12046,0 +12047,0 +12048,0 +12049,0 +12050,0 +12051,0 +12052,0 +12053,0 +12054,0 +12055,0 +12056,0 +12057,0 +12058,0 +12059,0 +12060,0 +12061,0 +12062,0 +12063,0 +12064,0 +12065,0 +12066,0 +12067,0 +12068,0 +12069,0 +12070,0 +12071,0 +12072,0 +12073,0 +12074,0 +12075,0 +12076,0 +12077,0 +12078,0 +12079,0 +12080,0 +12081,0 +12082,0 +12083,0 +12084,0 +12085,0 +12086,0 +12087,0 +12088,0 +12089,0 +12090,0 +12091,0 +12092,0 +12093,0 +12094,0 +12095,0 +12096,0 +12097,0 +12098,0 +12099,0 +12100,0 +12101,0 +12102,0 +12103,0 +12104,0 +12105,0 +12106,0 +12107,0 +12108,0 +12109,0 +12110,0 +12111,0 +12112,0 +12113,0 +12114,0 +12115,0 +12116,0 +12117,0 +12118,0 +12119,0 +12120,0 +12121,0 +12122,0 +12123,0 +12124,0 +12125,0 +12126,0 +12127,0 +12128,0 +12129,0 +12130,0 +12131,0 +12132,0 +12133,0 +12134,0 +12135,0 +12136,0 +12137,0 +12138,0 +12139,0 +12140,0 +12141,0 +12142,0 +12143,0 +12144,0 +12145,0 +12146,0 +12147,0 +12148,0 +12149,0 +12150,0 +12151,0 +12152,0 +12153,0 +12154,0 +12155,0 +12156,0 +12157,0 +12158,0 +12159,0 +12160,0 +12161,0 +12162,0 +12163,0 +12164,0 +12165,0 +12166,0 +12167,0 +12168,0 +12169,0 +12170,0 +12171,0 +12172,0 +12173,0 +12174,0 +12175,0 +12176,0 +12177,0 +12178,0 +12179,0 +12180,0 +12181,0 +12182,0 +12183,0 +12184,0 +12185,0 +12186,0 +12187,0 +12188,0 +12189,0 +12190,0 +12191,0 +12192,0 +12193,0 +12194,0 +12195,0 +12196,0 +12197,0 +12198,0 +12199,0 +12200,0 +12201,0 +12202,0 +12203,0 +12204,0 +12205,0 +12206,0 +12207,0 +12208,0 +12209,0 +12210,0 +12211,0 +12212,0 +12213,0 +12214,0 +12215,0 +12216,0 +12217,0 +12218,0 +12219,0 +12220,0 +12221,0 +12222,0 +12223,0 +12224,0 +12225,0 +12226,0 +12227,0 +12228,0 +12229,0 +12230,0 +12231,0 +12232,0 +12233,0 +12234,0 +12235,0 +12236,0 +12237,0 +12238,0 +12239,0 +12240,0 +12241,0 +12242,0 +12243,0 +12244,0 +12245,0 +12246,0 +12247,0 +12248,0 +12249,0 +12250,0 +12251,0 +12252,0 +12253,0 +12254,0 +12255,0 +12256,0 +12257,0 +12258,0 +12259,0 +12260,0 +12261,0 +12262,0 +12263,0 +12264,0 +12265,0 +12266,0 +12267,0 +12268,0 +12269,0 +12270,0 +12271,0 +12272,0 +12273,0 +12274,0 +12275,0 +12276,0 +12277,0 +12278,0 +12279,0 +12280,0 +12281,0 +12282,0 +12283,0 +12284,0 +12285,0 +12286,0 +12287,0 +12288,0 +12289,0 +12290,0 +12291,0 +12292,0 +12293,0 +12294,0 +12295,0 +12296,0 +12297,0 +12298,0 +12299,0 +12300,0 +12301,0 +12302,0 +12303,0 +12304,0 +12305,0 +12306,0 +12307,0 +12308,0 +12309,0 +12310,0 +12311,0 +12312,0 +12313,0 +12314,0 +12315,0 +12316,0 +12317,0 +12318,0 +12319,0 +12320,0 +12321,0 +12322,0 +12323,0 +12324,0 +12325,0 +12326,0 +12327,0 +12328,0 +12329,0 +12330,0 +12331,0 +12332,0 +12333,0 +12334,0 +12335,0 +12336,0 +12337,0 +12338,0 +12339,0 +12340,0 +12341,0 +12342,0 +12343,0 +12344,0 +12345,0 +12346,0 +12347,0 +12348,0 +12349,0 +12350,0 +12351,0 +12352,0 +12353,0 +12354,0 +12355,0 +12356,0 +12357,0 +12358,0 +12359,0 +12360,0 +12361,0 +12362,0 +12363,0 +12364,0 +12365,0 +12366,0 +12367,0 +12368,0 +12369,0 +12370,0 +12371,0 +12372,0 +12373,0 +12374,0 +12375,0 +12376,0 +12377,0 +12378,0 +12379,0 +12380,0 +12381,0 +12382,0 +12383,0 +12384,0 +12385,0 +12386,0 +12387,0 +12388,0 +12389,0 +12390,0 +12391,0 +12392,0 +12393,0 +12394,0 +12395,0 +12396,0 +12397,0 +12398,0 +12399,0 +12400,0 +12401,0 +12402,0 +12403,0 +12404,0 +12405,0 +12406,0 +12407,0 +12408,0 +12409,0 +12410,0 +12411,0 +12412,0 +12413,0 +12414,0 +12415,0 +12416,0 +12417,0 +12418,0 +12419,0 +12420,0 +12421,0 +12422,0 +12423,0 +12424,0 +12425,0 +12426,0 +12427,0 +12428,0 +12429,0 +12430,0 +12431,0 +12432,0 +12433,0 +12434,0 +12435,0 +12436,0 +12437,0 +12438,0 +12439,0 +12440,0 +12441,0 +12442,0 +12443,0 +12444,0 +12445,0 +12446,0 +12447,0 +12448,0 +12449,0 +12450,0 +12451,0 +12452,0 +12453,0 +12454,0 +12455,0 +12456,0 +12457,0 +12458,0 +12459,0 +12460,0 +12461,0 +12462,0 +12463,0 +12464,0 +12465,0 +12466,0 +12467,0 +12468,0 +12469,0 +12470,0 +12471,0 +12472,0 +12473,0 +12474,0 +12475,0 +12476,0 +12477,0 +12478,0 +12479,0 +12480,0 +12481,0 +12482,0 +12483,0 +12484,0 +12485,0 +12486,0 +12487,0 +12488,0 +12489,0 +12490,0 +12491,0 +12492,0 +12493,0 +12494,0 +12495,0 +12496,0 +12497,0 +12498,0 +12499,0 +12500,0 +12501,0 +12502,0 +12503,0 +12504,0 +12505,0 +12506,0 +12507,0 +12508,0 +12509,0 +12510,0 +12511,0 +12512,0 +12513,0 +12514,0 +12515,0 +12516,0 +12517,0 +12518,0 +12519,0 +12520,0 +12521,0 +12522,0 +12523,0 +12524,0 +12525,0 +12526,0 +12527,0 +12528,0 +12529,0 +12530,0 +12531,0 +12532,0 +12533,0 +12534,0 +12535,0 +12536,0 +12537,0 +12538,0 +12539,0 +12540,0 +12541,0 +12542,0 +12543,0 +12544,0 +12545,0 +12546,0 +12547,0 +12548,0 +12549,0 +12550,0 +12551,0 +12552,0 +12553,0 +12554,0 +12555,0 +12556,0 +12557,0 +12558,0 +12559,0 +12560,0 +12561,0 +12562,0 +12563,0 +12564,0 +12565,0 +12566,0 +12567,0 +12568,0 +12569,0 +12570,0 +12571,0 +12572,0 +12573,0 +12574,0 +12575,0 +12576,0 +12577,0 +12578,0 +12579,0 +12580,0 +12581,0 +12582,0 +12583,0 +12584,0 +12585,0 +12586,0 +12587,0 +12588,0 +12589,0 +12590,0 +12591,0 +12592,0 +12593,0 +12594,0 +12595,0 +12596,0 +12597,0 +12598,0 +12599,0 +12600,0 +12601,0 +12602,0 +12603,0 +12604,0 +12605,0 +12606,0 +12607,0 +12608,0 +12609,0 +12610,0 +12611,0 +12612,0 +12613,0 +12614,0 +12615,0 +12616,0 +12617,0 +12618,0 +12619,0 +12620,0 +12621,0 +12622,0 +12623,0 +12624,0 +12625,0 +12626,0 +12627,0 +12628,0 +12629,0 +12630,0 +12631,0 +12632,0 +12633,0 +12634,0 +12635,0 +12636,0 +12637,0 +12638,0 +12639,0 +12640,0 +12641,0 +12642,0 +12643,0 +12644,0 +12645,0 +12646,0 +12647,0 +12648,0 +12649,0 +12650,0 +12651,0 +12652,0 +12653,0 +12654,0 +12655,0 +12656,0 +12657,0 +12658,0 +12659,0 +12660,0 +12661,0 +12662,0 +12663,0 +12664,0 +12665,0 +12666,0 +12667,0 +12668,0 +12669,0 +12670,0 +12671,0 +12672,0 +12673,0 +12674,0 +12675,0 +12676,0 +12677,0 +12678,0 +12679,0 +12680,0 +12681,0 +12682,0 +12683,0 +12684,0 +12685,0 +12686,0 +12687,0 +12688,0 +12689,0 +12690,0 +12691,0 +12692,0 +12693,0 +12694,0 +12695,0 +12696,0 +12697,0 +12698,0 +12699,0 +12700,0 +12701,0 +12702,0 +12703,0 +12704,0 +12705,0 +12706,0 +12707,0 +12708,0 +12709,0 +12710,0 +12711,0 +12712,0 +12713,0 +12714,0 +12715,0 +12716,0 +12717,0 +12718,0 +12719,0 +12720,0 +12721,0 +12722,0 +12723,0 +12724,0 +12725,0 +12726,0 +12727,0 +12728,0 +12729,0 +12730,0 +12731,0 +12732,0 +12733,0 +12734,0 +12735,0 +12736,0 +12737,0 +12738,0 +12739,0 +12740,0 +12741,0 +12742,0 +12743,0 +12744,0 +12745,0 +12746,0 +12747,0 +12748,0 +12749,0 +12750,0 +12751,0 +12752,0 +12753,0 +12754,0 +12755,0 +12756,0 +12757,0 +12758,0 +12759,0 +12760,0 +12761,0 +12762,0 +12763,0 +12764,0 +12765,0 +12766,0 +12767,0 +12768,0 +12769,0 +12770,0 +12771,0 +12772,0 +12773,0 +12774,0 +12775,0 +12776,0 +12777,0 +12778,0 +12779,0 +12780,0 +12781,0 +12782,0 +12783,0 +12784,0 +12785,0 +12786,0 +12787,0 +12788,0 +12789,0 +12790,0 +12791,0 +12792,0 +12793,0 +12794,0 +12795,0 +12796,0 +12797,0 +12798,0 +12799,0 +12800,0 +12801,0 +12802,0 +12803,0 +12804,0 +12805,0 +12806,0 +12807,0 +12808,0 +12809,0 +12810,0 +12811,0 +12812,0 +12813,0 +12814,0 +12815,0 +12816,0 +12817,0 +12818,0 +12819,0 +12820,0 +12821,0 +12822,0 +12823,0 +12824,0 +12825,0 +12826,0 +12827,0 +12828,0 +12829,0 +12830,0 +12831,0 +12832,0 +12833,0 +12834,0 +12835,0 +12836,0 +12837,0 +12838,0 +12839,0 +12840,0 +12841,0 +12842,0 +12843,0 +12844,0 +12845,0 +12846,0 +12847,0 +12848,0 +12849,0 +12850,0 +12851,0 +12852,0 +12853,0 +12854,0 +12855,0 +12856,0 +12857,0 +12858,0 +12859,0 +12860,0 +12861,0 +12862,0 +12863,0 +12864,0 +12865,0 +12866,0 +12867,0 +12868,0 +12869,0 +12870,0 +12871,0 +12872,0 +12873,0 +12874,0 +12875,0 +12876,0 +12877,0 +12878,0 +12879,0 +12880,0 +12881,0 +12882,0 +12883,0 +12884,0 +12885,0 +12886,0 +12887,0 +12888,0 +12889,0 +12890,0 +12891,0 +12892,0 +12893,0 +12894,0 +12895,0 +12896,0 +12897,0 +12898,0 +12899,0 +12900,0 +12901,0 +12902,0 +12903,0 +12904,0 +12905,0 +12906,0 +12907,0 +12908,0 +12909,0 +12910,0 +12911,0 +12912,0 +12913,0 +12914,0 +12915,0 +12916,0 +12917,0 +12918,0 +12919,0 +12920,0 +12921,0 +12922,0 +12923,0 +12924,0 +12925,0 +12926,0 +12927,0 +12928,0 +12929,0 +12930,0 +12931,0 +12932,0 +12933,0 +12934,0 +12935,0 +12936,0 +12937,0 +12938,0 +12939,0 +12940,0 +12941,0 +12942,0 +12943,0 +12944,0 +12945,0 +12946,0 +12947,0 +12948,0 +12949,0 +12950,0 +12951,0 +12952,0 +12953,0 +12954,0 +12955,0 +12956,0 +12957,0 +12958,0 +12959,0 +12960,0 +12961,0 +12962,0 +12963,0 +12964,0 +12965,0 +12966,0 +12967,0 +12968,0 +12969,0 +12970,0 +12971,0 +12972,0 +12973,0 +12974,0 +12975,0 +12976,0 +12977,0 +12978,0 +12979,0 +12980,0 +12981,0 +12982,0 +12983,0 +12984,0 +12985,0 +12986,0 +12987,0 +12988,0 +12989,0 +12990,0 +12991,0 +12992,0 +12993,0 +12994,0 +12995,0 +12996,0 +12997,0 +12998,0 +12999,0 +13000,0 +13001,0 +13002,0 +13003,0 +13004,0 +13005,0 +13006,0 +13007,0 +13008,0 +13009,0 +13010,0 +13011,0 +13012,0 +13013,0 +13014,0 +13015,0 +13016,0 +13017,0 +13018,0 +13019,0 +13020,0 +13021,0 +13022,0 +13023,0 +13024,0 +13025,0 +13026,0 +13027,0 +13028,0 +13029,0 +13030,0 +13031,0 +13032,0 +13033,0 +13034,0 +13035,0 +13036,0 +13037,0 +13038,0 +13039,0 +13040,0 +13041,0 +13042,0 +13043,0 +13044,0 +13045,0 +13046,0 +13047,0 +13048,0 +13049,0 +13050,0 +13051,0 +13052,0 +13053,0 +13054,0 +13055,0 +13056,0 +13057,0 +13058,0 +13059,0 +13060,0 +13061,0 +13062,0 +13063,0 +13064,0 +13065,0 +13066,0 +13067,0 +13068,0 +13069,0 +13070,0 +13071,0 +13072,0 +13073,0 +13074,0 +13075,0 +13076,0 +13077,0 +13078,0 +13079,0 +13080,0 +13081,0 +13082,0 +13083,0 +13084,0 +13085,0 +13086,0 +13087,0 +13088,0 +13089,0 +13090,0 +13091,0 +13092,0 +13093,0 +13094,0 +13095,0 +13096,0 +13097,0 +13098,0 +13099,0 +13100,0 +13101,0 +13102,0 +13103,0 +13104,0 +13105,0 +13106,0 +13107,0 +13108,0 +13109,0 +13110,0 +13111,0 +13112,0 +13113,0 +13114,0 +13115,0 +13116,0 +13117,0 +13118,0 +13119,0 +13120,0 +13121,0 +13122,0 +13123,0 +13124,0 +13125,0 +13126,0 +13127,0 +13128,0 +13129,0 +13130,0 +13131,0 +13132,0 +13133,0 +13134,0 +13135,0 +13136,0 +13137,0 +13138,0 +13139,0 +13140,0 +13141,0 +13142,0 +13143,0 +13144,0 +13145,0 +13146,0 +13147,0 +13148,0 +13149,0 +13150,0 +13151,0 +13152,0 +13153,0 +13154,0 +13155,0 +13156,0 +13157,0 +13158,0 +13159,0 +13160,0 +13161,0 +13162,0 +13163,0 +13164,0 +13165,0 +13166,0 +13167,0 +13168,0 +13169,0 +13170,0 +13171,0 +13172,0 +13173,0 +13174,0 +13175,0 +13176,0 +13177,0 +13178,0 +13179,0 +13180,0 +13181,0 +13182,0 +13183,0 +13184,0 +13185,0 +13186,0 +13187,0 +13188,0 +13189,0 +13190,0 +13191,0 +13192,0 +13193,0 +13194,0 +13195,0 +13196,0 +13197,0 +13198,0 +13199,0 +13200,0 +13201,0 +13202,0 +13203,0 +13204,0 +13205,0 +13206,0 +13207,0 +13208,0 +13209,0 +13210,0 +13211,0 +13212,0 +13213,0 +13214,0 +13215,0 +13216,0 +13217,0 +13218,0 +13219,0 +13220,0 +13221,0 +13222,0 +13223,0 +13224,0 +13225,0 +13226,0 +13227,0 +13228,0 +13229,0 +13230,0 +13231,0 +13232,0 +13233,0 +13234,0 +13235,0 +13236,0 +13237,0 +13238,0 +13239,0 +13240,0 +13241,0 +13242,0 +13243,0 +13244,0 +13245,0 +13246,0 +13247,0 +13248,0 +13249,0 +13250,0 +13251,0 +13252,0 +13253,0 +13254,0 +13255,0 +13256,0 +13257,0 +13258,0 +13259,0 +13260,0 +13261,0 +13262,0 +13263,0 +13264,0 +13265,0 +13266,0 +13267,0 +13268,0 +13269,0 +13270,0 +13271,0 +13272,0 +13273,0 +13274,0 +13275,0 +13276,0 +13277,0 +13278,0 +13279,0 +13280,0 +13281,0 +13282,0 +13283,0 +13284,0 +13285,0 +13286,0 +13287,0 +13288,0 +13289,0 +13290,0 +13291,0 +13292,0 +13293,0 +13294,0 +13295,0 +13296,0 +13297,0 +13298,0 +13299,0 +13300,0 +13301,0 +13302,0 +13303,0 +13304,0 +13305,0 +13306,0 +13307,0 +13308,0 +13309,0 +13310,0 +13311,0 +13312,0 +13313,0 +13314,0 +13315,0 +13316,0 +13317,0 +13318,0 +13319,0 +13320,0 +13321,0 +13322,0 +13323,0 +13324,0 +13325,0 +13326,0 +13327,0 +13328,0 +13329,0 +13330,0 +13331,0 +13332,0 +13333,0 +13334,0 +13335,0 +13336,0 +13337,0 +13338,0 +13339,0 +13340,0 +13341,0 +13342,0 +13343,0 +13344,0 +13345,0 +13346,0 +13347,0 +13348,0 +13349,0 +13350,0 +13351,0 +13352,0 +13353,0 +13354,0 +13355,0 +13356,0 +13357,0 +13358,0 +13359,0 +13360,0 +13361,0 +13362,0 +13363,0 +13364,0 +13365,0 +13366,0 +13367,0 +13368,0 +13369,0 +13370,0 +13371,0 +13372,0 +13373,0 +13374,0 +13375,0 +13376,0 +13377,0 +13378,0 +13379,0 +13380,0 +13381,0 +13382,0 +13383,0 +13384,0 +13385,0 +13386,0 +13387,0 +13388,0 +13389,0 +13390,0 +13391,0 +13392,0 +13393,0 +13394,0 +13395,0 +13396,0 +13397,0 +13398,0 +13399,0 +13400,0 +13401,0 +13402,0 +13403,0 +13404,0 +13405,0 +13406,0 +13407,0 +13408,0 +13409,0 +13410,0 +13411,0 +13412,0 +13413,0 +13414,0 +13415,0 +13416,0 +13417,0 +13418,0 +13419,0 +13420,0 +13421,0 +13422,0 +13423,0 +13424,0 +13425,0 +13426,0 +13427,0 +13428,0 +13429,0 +13430,0 +13431,0 +13432,0 +13433,0 +13434,0 +13435,0 +13436,0 +13437,0 +13438,0 +13439,0 +13440,0 +13441,0 +13442,0 +13443,0 +13444,0 +13445,0 +13446,0 +13447,0 +13448,0 +13449,0 +13450,0 +13451,0 +13452,0 +13453,0 +13454,0 +13455,0 +13456,0 +13457,0 +13458,0 +13459,0 +13460,0 +13461,0 +13462,0 +13463,0 +13464,0 +13465,0 +13466,0 +13467,0 +13468,0 +13469,0 +13470,0 +13471,0 +13472,0 +13473,0 +13474,0 +13475,0 +13476,0 +13477,0 +13478,0 +13479,0 +13480,0 +13481,0 +13482,0 +13483,0 +13484,0 +13485,0 +13486,0 +13487,0 +13488,0 +13489,0 +13490,0 +13491,0 +13492,0 +13493,0 +13494,0 +13495,0 +13496,0 +13497,0 +13498,0 +13499,0 +13500,0 +13501,0 +13502,0 +13503,0 +13504,0 +13505,0 +13506,0 +13507,0 +13508,0 +13509,0 +13510,0 +13511,0 +13512,0 +13513,0 +13514,0 +13515,0 +13516,0 +13517,0 +13518,0 +13519,0 +13520,0 +13521,0 +13522,0 +13523,0 +13524,0 +13525,0 +13526,0 +13527,0 +13528,0 +13529,0 +13530,0 +13531,0 +13532,0 +13533,0 +13534,0 +13535,0 +13536,0 +13537,0 +13538,0 +13539,0 +13540,0 +13541,0 +13542,0 +13543,0 +13544,0 +13545,0 +13546,0 +13547,0 +13548,0 +13549,0 +13550,0 +13551,0 +13552,0 +13553,0 +13554,0 +13555,0 +13556,0 +13557,0 +13558,0 +13559,0 +13560,0 +13561,0 +13562,0 +13563,0 +13564,0 +13565,0 +13566,0 +13567,0 +13568,0 +13569,0 +13570,0 +13571,0 +13572,0 +13573,0 +13574,0 +13575,0 +13576,0 +13577,0 +13578,0 +13579,0 +13580,0 +13581,0 +13582,0 +13583,0 +13584,0 +13585,0 +13586,0 +13587,0 +13588,0 +13589,0 +13590,0 +13591,0 +13592,0 +13593,0 +13594,0 +13595,0 +13596,0 +13597,0 +13598,0 +13599,0 +13600,0 +13601,0 +13602,0 +13603,0 +13604,0 +13605,0 +13606,0 +13607,0 +13608,0 +13609,0 +13610,0 +13611,0 +13612,0 +13613,0 +13614,0 +13615,0 +13616,0 +13617,0 +13618,0 +13619,0 +13620,0 +13621,0 +13622,0 +13623,0 +13624,0 +13625,0 +13626,0 +13627,0 +13628,0 +13629,0 +13630,0 +13631,0 +13632,0 +13633,0 +13634,0 +13635,0 +13636,0 +13637,0 +13638,0 +13639,0 +13640,0 +13641,0 +13642,0 +13643,0 +13644,0 +13645,0 +13646,0 +13647,0 +13648,0 +13649,0 +13650,0 +13651,0 +13652,0 +13653,0 +13654,0 +13655,0 +13656,0 +13657,0 +13658,0 +13659,0 +13660,0 +13661,0 +13662,0 +13663,0 +13664,0 +13665,0 +13666,0 +13667,0 +13668,0 +13669,0 +13670,0 +13671,0 +13672,0 +13673,0 +13674,0 +13675,0 +13676,0 +13677,0 +13678,0 +13679,0 +13680,0 +13681,0 +13682,0 +13683,0 +13684,0 +13685,0 +13686,0 +13687,0 +13688,0 +13689,0 +13690,0 +13691,0 +13692,0 +13693,0 +13694,0 +13695,0 +13696,0 +13697,0 +13698,0 +13699,0 +13700,0 +13701,0 +13702,0 +13703,0 +13704,0 +13705,0 +13706,0 +13707,0 +13708,0 +13709,0 +13710,0 +13711,0 +13712,0 +13713,0 +13714,0 +13715,0 +13716,0 +13717,0 +13718,0 +13719,0 +13720,0 +13721,0 +13722,0 +13723,0 +13724,0 +13725,0 +13726,0 +13727,0 +13728,0 +13729,0 +13730,0 +13731,0 +13732,0 +13733,0 +13734,0 +13735,0 +13736,0 +13737,0 +13738,0 +13739,0 +13740,0 +13741,0 +13742,0 +13743,0 +13744,0 +13745,0 +13746,0 +13747,0 +13748,0 +13749,0 +13750,0 +13751,0 +13752,0 +13753,0 +13754,0 +13755,0 +13756,0 +13757,0 +13758,0 +13759,0 +13760,0 +13761,0 +13762,0 +13763,0 +13764,0 +13765,0 +13766,0 +13767,0 +13768,0 +13769,0 +13770,0 +13771,0 +13772,0 +13773,0 +13774,0 +13775,0 +13776,0 +13777,0 +13778,0 +13779,0 +13780,0 +13781,0 +13782,0 +13783,0 +13784,0 +13785,0 +13786,0 +13787,0 +13788,0 +13789,0 +13790,0 +13791,0 +13792,0 +13793,0 +13794,0 +13795,0 +13796,0 +13797,0 +13798,0 +13799,0 +13800,0 +13801,0 +13802,0 +13803,0 +13804,0 +13805,0 +13806,0 +13807,0 +13808,0 +13809,0 +13810,0 +13811,0 +13812,0 +13813,0 +13814,0 +13815,0 +13816,0 +13817,0 +13818,0 +13819,0 +13820,0 +13821,0 +13822,0 +13823,0 +13824,0 +13825,0 +13826,0 +13827,0 +13828,0 +13829,0 +13830,0 +13831,0 +13832,0 +13833,0 +13834,0 +13835,0 +13836,0 +13837,0 +13838,0 +13839,0 +13840,0 +13841,0 +13842,0 +13843,0 +13844,0 +13845,0 +13846,0 +13847,0 +13848,0 +13849,0 +13850,0 +13851,0 +13852,0 +13853,0 +13854,0 +13855,0 +13856,0 +13857,0 +13858,0 +13859,0 +13860,0 +13861,0 +13862,0 +13863,0 +13864,0 +13865,0 +13866,0 +13867,0 +13868,0 +13869,0 +13870,0 +13871,0 +13872,0 +13873,0 +13874,0 +13875,0 +13876,0 +13877,0 +13878,0 +13879,0 +13880,0 +13881,0 +13882,0 +13883,0 +13884,0 +13885,0 +13886,0 +13887,0 +13888,0 +13889,0 +13890,0 +13891,0 +13892,0 +13893,0 +13894,0 +13895,0 +13896,0 +13897,0 +13898,0 +13899,0 +13900,0 +13901,0 +13902,0 +13903,0 +13904,0 +13905,0 +13906,0 +13907,0 +13908,0 +13909,0 +13910,0 +13911,0 +13912,0 +13913,0 +13914,0 +13915,0 +13916,0 +13917,0 +13918,0 +13919,0 +13920,0 +13921,0 +13922,0 +13923,0 +13924,0 +13925,0 +13926,0 +13927,0 +13928,0 +13929,0 +13930,0 +13931,0 +13932,0 +13933,0 +13934,0 +13935,0 +13936,0 +13937,0 +13938,0 +13939,0 +13940,0 +13941,0 +13942,0 +13943,0 +13944,0 +13945,0 +13946,0 +13947,0 +13948,0 +13949,0 +13950,0 +13951,0 +13952,0 +13953,0 +13954,0 +13955,0 +13956,0 +13957,0 +13958,0 +13959,0 +13960,0 +13961,0 +13962,0 +13963,0 +13964,0 +13965,0 +13966,0 +13967,0 +13968,0 +13969,0 +13970,0 +13971,0 +13972,0 +13973,0 +13974,0 +13975,0 +13976,0 +13977,0 +13978,0 +13979,0 +13980,0 +13981,0 +13982,0 +13983,0 +13984,0 +13985,0 +13986,0 +13987,0 +13988,0 +13989,0 +13990,0 +13991,0 +13992,0 +13993,0 +13994,0 +13995,0 +13996,0 +13997,0 +13998,0 +13999,0 +14000,0 +14001,0 +14002,0 +14003,0 +14004,0 +14005,0 +14006,0 +14007,0 +14008,0 +14009,0 +14010,0 +14011,0 +14012,0 +14013,0 +14014,0 +14015,0 +14016,0 +14017,0 +14018,0 +14019,0 +14020,0 +14021,0 +14022,0 +14023,0 +14024,0 +14025,0 +14026,0 +14027,0 +14028,0 +14029,0 +14030,0 +14031,0 +14032,0 +14033,0 +14034,0 +14035,0 +14036,0 +14037,0 +14038,0 +14039,0 +14040,0 +14041,0 +14042,0 +14043,0 +14044,0 +14045,0 +14046,0 +14047,0 +14048,0 +14049,0 +14050,0 +14051,0 +14052,0 +14053,0 +14054,0 +14055,0 +14056,0 +14057,0 +14058,0 +14059,0 +14060,0 +14061,0 +14062,0 +14063,0 +14064,0 +14065,0 +14066,0 +14067,0 +14068,0 +14069,0 +14070,0 +14071,0 +14072,0 +14073,0 +14074,0 +14075,0 +14076,0 +14077,0 +14078,0 +14079,0 +14080,0 +14081,0 +14082,0 +14083,0 +14084,0 +14085,0 +14086,0 +14087,0 +14088,0 +14089,0 +14090,0 +14091,0 +14092,0 +14093,0 +14094,0 +14095,0 +14096,0 +14097,0 +14098,0 +14099,0 +14100,0 +14101,0 +14102,0 +14103,0 +14104,0 +14105,0 +14106,0 +14107,0 +14108,0 +14109,0 +14110,0 +14111,0 +14112,0 +14113,0 +14114,0 +14115,0 +14116,0 +14117,0 +14118,0 +14119,0 +14120,0 +14121,0 +14122,0 +14123,0 +14124,0 +14125,0 +14126,0 +14127,0 +14128,0 +14129,0 +14130,0 +14131,0 +14132,0 +14133,0 +14134,0 +14135,0 +14136,0 +14137,0 +14138,0 +14139,0 +14140,0 +14141,0 +14142,0 +14143,0 +14144,0 +14145,0 +14146,0 +14147,0 +14148,0 +14149,0 +14150,0 +14151,0 +14152,0 +14153,0 +14154,0 +14155,0 +14156,0 +14157,0 +14158,0 +14159,0 +14160,0 +14161,0 +14162,0 +14163,0 +14164,0 +14165,0 +14166,0 +14167,0 +14168,0 +14169,0 +14170,0 +14171,0 +14172,0 +14173,0 +14174,0 +14175,0 +14176,0 +14177,0 +14178,0 +14179,0 +14180,0 +14181,0 +14182,0 +14183,0 +14184,0 +14185,0 +14186,0 +14187,0 +14188,0 +14189,0 +14190,0 +14191,0 +14192,0 +14193,0 +14194,0 +14195,0 +14196,0 +14197,0 +14198,0 +14199,0 +14200,0 +14201,0 +14202,0 +14203,0 +14204,0 +14205,0 +14206,0 +14207,0 +14208,0 +14209,0 +14210,0 +14211,0 +14212,0 +14213,0 +14214,0 +14215,0 +14216,0 +14217,0 +14218,0 +14219,0 +14220,0 +14221,0 +14222,0 +14223,0 +14224,0 +14225,0 +14226,0 +14227,0 +14228,0 +14229,0 +14230,0 +14231,0 +14232,0 +14233,0 +14234,0 +14235,0 +14236,0 +14237,0 +14238,0 +14239,0 +14240,0 +14241,0 +14242,0 +14243,0 +14244,0 +14245,0 +14246,0 +14247,0 +14248,0 +14249,0 +14250,0 +14251,0 +14252,0 +14253,0 +14254,0 +14255,0 +14256,0 +14257,0 +14258,0 +14259,0 +14260,0 +14261,0 +14262,0 +14263,0 +14264,0 +14265,0 +14266,0 +14267,0 +14268,0 +14269,0 +14270,0 +14271,0 +14272,0 +14273,0 +14274,0 +14275,0 +14276,0 +14277,0 +14278,0 +14279,0 +14280,0 +14281,0 +14282,0 +14283,0 +14284,0 +14285,0 +14286,0 +14287,0 +14288,0 +14289,0 +14290,0 +14291,0 +14292,0 +14293,0 +14294,0 +14295,0 +14296,0 +14297,0 +14298,0 +14299,0 +14300,0 +14301,0 +14302,0 +14303,0 +14304,0 +14305,0 +14306,0 +14307,0 +14308,0 +14309,0 +14310,0 +14311,0 +14312,0 +14313,0 +14314,0 +14315,0 +14316,0 +14317,0 +14318,0 +14319,0 +14320,0 +14321,0 +14322,0 +14323,0 +14324,0 +14325,0 +14326,0 +14327,0 +14328,0 +14329,0 +14330,0 +14331,0 +14332,0 +14333,0 +14334,0 +14335,0 +14336,0 +14337,0 +14338,0 +14339,0 +14340,0 +14341,0 +14342,0 +14343,0 +14344,0 +14345,0 +14346,0 +14347,0 +14348,0 +14349,0 +14350,0 +14351,0 +14352,0 +14353,0 +14354,0 +14355,0 +14356,0 +14357,0 +14358,0 +14359,0 +14360,0 +14361,0 +14362,0 +14363,0 +14364,0 +14365,0 +14366,0 +14367,0 +14368,0 +14369,0 +14370,0 +14371,0 +14372,0 +14373,0 +14374,0 +14375,0 +14376,0 +14377,0 +14378,0 +14379,0 +14380,0 +14381,0 +14382,0 +14383,0 +14384,0 +14385,0 +14386,0 +14387,0 +14388,0 +14389,0 +14390,0 +14391,0 +14392,0 +14393,0 +14394,0 +14395,0 +14396,0 +14397,0 +14398,0 +14399,0 +14400,0 +14401,0 +14402,0 +14403,0 +14404,0 +14405,0 +14406,0 +14407,0 +14408,0 +14409,0 +14410,0 +14411,0 +14412,0 +14413,0 +14414,0 +14415,0 +14416,0 +14417,0 +14418,0 +14419,0 +14420,0 +14421,0 +14422,0 +14423,0 +14424,0 +14425,0 +14426,0 +14427,0 +14428,0 +14429,0 +14430,0 +14431,0 +14432,0 +14433,0 +14434,0 +14435,0 +14436,0 +14437,0 +14438,0 +14439,0 +14440,0 +14441,0 +14442,0 +14443,0 +14444,0 +14445,0 +14446,0 +14447,0 +14448,0 +14449,0 +14450,0 +14451,0 +14452,0 +14453,0 +14454,0 +14455,0 +14456,0 +14457,0 +14458,0 +14459,0 +14460,0 +14461,0 +14462,0 +14463,0 +14464,0 +14465,0 +14466,0 +14467,0 +14468,0 +14469,0 +14470,0 +14471,0 +14472,0 +14473,0 +14474,0 +14475,0 +14476,0 +14477,0 +14478,0 +14479,0 +14480,0 +14481,0 +14482,0 +14483,0 +14484,0 +14485,0 +14486,0 +14487,0 +14488,0 +14489,0 +14490,0 +14491,0 +14492,0 +14493,0 +14494,0 +14495,0 +14496,0 +14497,0 +14498,0 +14499,0 +14500,0 +14501,0 +14502,0 +14503,0 +14504,0 +14505,0 +14506,0 +14507,0 +14508,0 +14509,0 +14510,0 +14511,0 +14512,0 +14513,0 +14514,0 +14515,0 +14516,0 +14517,0 +14518,0 +14519,0 +14520,0 +14521,0 +14522,0 +14523,0 +14524,0 +14525,0 +14526,0 +14527,0 +14528,0 +14529,0 +14530,0 +14531,0 +14532,0 +14533,0 +14534,0 +14535,0 +14536,0 +14537,0 +14538,0 +14539,0 +14540,0 +14541,0 +14542,0 +14543,0 +14544,0 +14545,0 +14546,0 +14547,0 +14548,0 +14549,0 +14550,0 +14551,0 +14552,0 +14553,0 +14554,0 +14555,0 +14556,0 +14557,0 +14558,0 +14559,0 +14560,0 +14561,0 +14562,0 +14563,0 +14564,0 +14565,0 +14566,0 +14567,0 +14568,0 +14569,0 +14570,0 +14571,0 +14572,0 +14573,0 +14574,0 +14575,0 +14576,0 +14577,0 +14578,0 +14579,0 +14580,0 +14581,0 +14582,0 +14583,0 +14584,0 +14585,0 +14586,0 +14587,0 +14588,0 +14589,0 +14590,0 +14591,0 +14592,0 +14593,0 +14594,0 +14595,0 +14596,0 +14597,0 +14598,0 +14599,0 +14600,0 +14601,0 +14602,0 +14603,0 +14604,0 +14605,0 +14606,0 +14607,0 +14608,0 +14609,0 +14610,0 +14611,0 +14612,0 +14613,0 +14614,0 +14615,0 +14616,0 +14617,0 +14618,0 +14619,0 +14620,0 +14621,0 +14622,0 +14623,0 +14624,0 +14625,0 +14626,0 +14627,0 +14628,0 +14629,0 +14630,0 +14631,0 +14632,0 +14633,0 +14634,0 +14635,0 +14636,0 +14637,0 +14638,0 +14639,0 +14640,0 +14641,0 +14642,0 +14643,0 +14644,0 +14645,0 +14646,0 +14647,0 +14648,0 +14649,0 +14650,0 +14651,0 +14652,0 +14653,0 +14654,0 +14655,0 +14656,0 +14657,0 +14658,0 +14659,0 +14660,0 +14661,0 +14662,0 +14663,0 +14664,0 +14665,0 +14666,0 +14667,0 +14668,0 +14669,0 +14670,0 +14671,0 +14672,0 +14673,0 +14674,0 +14675,0 +14676,0 +14677,0 +14678,0 +14679,0 +14680,0 +14681,0 +14682,0 +14683,0 +14684,0 +14685,0 +14686,0 +14687,0 +14688,0 +14689,0 +14690,0 +14691,0 +14692,0 +14693,0 +14694,0 +14695,0 +14696,0 +14697,0 +14698,0 +14699,0 +14700,0 +14701,0 +14702,0 +14703,0 +14704,0 +14705,0 +14706,0 +14707,0 +14708,0 +14709,0 +14710,0 +14711,0 +14712,0 +14713,0 +14714,0 +14715,0 +14716,0 +14717,0 +14718,0 +14719,0 +14720,0 +14721,0 +14722,0 +14723,0 +14724,0 +14725,0 +14726,0 +14727,0 +14728,0 +14729,0 +14730,0 +14731,0 +14732,0 +14733,0 +14734,0 +14735,0 +14736,0 +14737,0 +14738,0 +14739,0 +14740,0 +14741,0 +14742,0 +14743,0 +14744,0 +14745,0 +14746,0 +14747,0 +14748,0 +14749,0 +14750,0 +14751,0 +14752,0 +14753,0 +14754,0 +14755,0 +14756,0 +14757,0 +14758,0 +14759,0 +14760,0 +14761,0 +14762,0 +14763,0 +14764,0 +14765,0 +14766,0 +14767,0 +14768,0 +14769,0 +14770,0 +14771,0 +14772,0 +14773,0 +14774,0 +14775,0 +14776,0 +14777,0 +14778,0 +14779,0 +14780,0 +14781,0 +14782,0 +14783,0 +14784,0 +14785,0 +14786,0 +14787,0 +14788,0 +14789,0 +14790,0 +14791,0 +14792,0 +14793,0 +14794,0 +14795,0 +14796,0 +14797,0 +14798,0 +14799,0 +14800,0 +14801,0 +14802,0 +14803,0 +14804,0 +14805,0 +14806,0 +14807,0 +14808,0 +14809,0 +14810,0 +14811,0 +14812,0 +14813,0 +14814,0 +14815,0 +14816,0 +14817,0 +14818,0 +14819,0 +14820,0 +14821,0 +14822,0 +14823,0 +14824,0 +14825,0 +14826,0 +14827,0 +14828,0 +14829,0 +14830,0 +14831,0 +14832,0 +14833,0 +14834,0 +14835,0 +14836,0 +14837,0 +14838,0 +14839,0 +14840,0 +14841,0 +14842,0 +14843,0 +14844,0 +14845,0 +14846,0 +14847,0 +14848,0 +14849,0 +14850,0 +14851,0 +14852,0 +14853,0 +14854,0 +14855,0 +14856,0 +14857,0 +14858,0 +14859,0 +14860,0 +14861,0 +14862,0 +14863,0 +14864,0 +14865,0 +14866,0 +14867,0 +14868,0 +14869,0 +14870,0 +14871,0 +14872,0 +14873,0 +14874,0 +14875,0 +14876,0 +14877,0 +14878,0 +14879,0 +14880,0 +14881,0 +14882,0 +14883,0 +14884,0 +14885,0 +14886,0 +14887,0 +14888,0 +14889,0 +14890,0 +14891,0 +14892,0 +14893,0 +14894,0 +14895,0 +14896,0 +14897,0 +14898,0 +14899,0 +14900,0 +14901,0 +14902,0 +14903,0 +14904,0 +14905,0 +14906,0 +14907,0 +14908,0 +14909,0 +14910,0 +14911,0 +14912,0 +14913,0 +14914,0 +14915,0 +14916,0 +14917,0 +14918,0 +14919,0 +14920,0 +14921,0 +14922,0 +14923,0 +14924,0 +14925,0 +14926,0 +14927,0 +14928,0 +14929,0 +14930,0 +14931,0 +14932,0 +14933,0 +14934,0 +14935,0 +14936,0 +14937,0 +14938,0 +14939,0 +14940,0 +14941,0 +14942,0 +14943,0 +14944,0 +14945,0 +14946,0 +14947,0 +14948,0 +14949,0 +14950,0 +14951,0 +14952,0 +14953,0 +14954,0 +14955,0 +14956,0 +14957,0 +14958,0 +14959,0 +14960,0 +14961,0 +14962,0 +14963,0 +14964,0 +14965,0 +14966,0 +14967,0 +14968,0 +14969,0 +14970,0 +14971,0 +14972,0 +14973,0 +14974,0 +14975,0 +14976,0 +14977,0 +14978,0 +14979,0 +14980,0 +14981,0 +14982,0 +14983,0 +14984,0 +14985,0 +14986,0 +14987,0 +14988,0 +14989,0 +14990,0 +14991,0 +14992,0 +14993,0 +14994,0 +14995,0 +14996,0 +14997,0 +14998,0 +14999,0 +15000,0 +15001,0 +15002,0 +15003,0 +15004,0 +15005,0 +15006,0 +15007,0 +15008,0 +15009,0 +15010,0 +15011,0 +15012,0 +15013,0 +15014,0 +15015,0 +15016,0 +15017,0 +15018,0 +15019,0 +15020,0 +15021,0 +15022,0 +15023,0 +15024,0 +15025,0 +15026,0 +15027,0 +15028,0 +15029,0 +15030,0 +15031,0 +15032,0 +15033,0 +15034,0 +15035,0 +15036,0 +15037,0 +15038,0 +15039,0 +15040,0 +15041,0 +15042,0 +15043,0 +15044,0 +15045,0 +15046,0 +15047,0 +15048,0 +15049,0 +15050,0 +15051,0 +15052,0 +15053,0 +15054,0 +15055,0 +15056,0 +15057,0 +15058,0 +15059,0 +15060,0 +15061,0 +15062,0 +15063,0 +15064,0 +15065,0 +15066,0 +15067,0 +15068,0 +15069,0 +15070,0 +15071,0 +15072,0 +15073,0 +15074,0 +15075,0 +15076,0 +15077,0 +15078,0 +15079,0 +15080,0 +15081,0 +15082,0 +15083,0 +15084,0 +15085,0 +15086,0 +15087,0 +15088,0 +15089,0 +15090,0 +15091,0 +15092,0 +15093,0 +15094,0 +15095,0 +15096,0 +15097,0 +15098,0 +15099,0 +15100,0 +15101,0 +15102,0 +15103,0 +15104,0 +15105,0 +15106,0 +15107,0 +15108,0 +15109,0 +15110,0 +15111,0 +15112,0 +15113,0 +15114,0 +15115,0 +15116,0 +15117,0 +15118,0 +15119,0 +15120,0 +15121,0 +15122,0 +15123,0 +15124,0 +15125,0 +15126,0 +15127,0 +15128,0 +15129,0 +15130,0 +15131,0 +15132,0 +15133,0 +15134,0 +15135,0 +15136,0 +15137,0 +15138,0 +15139,0 +15140,0 +15141,0 +15142,0 +15143,0 +15144,0 +15145,0 +15146,0 +15147,0 +15148,0 +15149,0 +15150,0 +15151,0 +15152,0 +15153,0 +15154,0 +15155,0 +15156,0 +15157,0 +15158,0 +15159,0 +15160,0 +15161,0 +15162,0 +15163,0 +15164,0 +15165,0 +15166,0 +15167,0 +15168,0 +15169,0 +15170,0 +15171,0 +15172,0 +15173,0 +15174,0 +15175,0 +15176,0 +15177,0 +15178,0 +15179,0 +15180,0 +15181,0 +15182,0 +15183,0 +15184,0 +15185,0 +15186,0 +15187,0 +15188,0 +15189,0 +15190,0 +15191,0 +15192,0 +15193,0 +15194,0 +15195,0 +15196,0 +15197,0 +15198,0 +15199,0 +15200,0 +15201,0 +15202,0 +15203,0 +15204,0 +15205,0 +15206,0 +15207,0 +15208,0 +15209,0 +15210,0 +15211,0 +15212,0 +15213,0 +15214,0 +15215,0 +15216,0 +15217,0 +15218,0 +15219,0 +15220,0 +15221,0 +15222,0 +15223,0 +15224,0 +15225,0 +15226,0 +15227,0 +15228,0 +15229,0 +15230,0 +15231,0 +15232,0 +15233,0 +15234,0 +15235,0 +15236,0 +15237,0 +15238,0 +15239,0 +15240,0 +15241,0 +15242,0 +15243,0 +15244,0 +15245,0 +15246,0 +15247,0 +15248,0 +15249,0 +15250,0 +15251,0 +15252,0 +15253,0 +15254,0 +15255,0 +15256,0 +15257,0 +15258,0 +15259,0 +15260,0 +15261,0 +15262,0 +15263,0 +15264,0 +15265,0 +15266,0 +15267,0 +15268,0 +15269,0 +15270,0 +15271,0 +15272,0 +15273,0 +15274,0 +15275,0 +15276,0 +15277,0 +15278,0 +15279,0 +15280,0 +15281,0 +15282,0 +15283,0 +15284,0 +15285,0 +15286,0 +15287,0 +15288,0 +15289,0 +15290,0 +15291,0 +15292,0 +15293,0 +15294,0 +15295,0 +15296,0 +15297,0 +15298,0 +15299,0 +15300,0 +15301,0 +15302,0 +15303,0 +15304,0 +15305,0 +15306,0 +15307,0 +15308,0 +15309,0 +15310,0 +15311,0 +15312,0 +15313,0 +15314,0 +15315,0 +15316,0 +15317,0 +15318,0 +15319,0 +15320,0 +15321,0 +15322,0 +15323,0 +15324,0 +15325,0 +15326,0 +15327,0 +15328,0 +15329,0 +15330,0 +15331,0 +15332,0 +15333,0 +15334,0 +15335,0 +15336,0 +15337,0 +15338,0 +15339,0 +15340,0 +15341,0 +15342,0 +15343,0 +15344,0 +15345,0 +15346,0 +15347,0 +15348,0 +15349,0 +15350,0 +15351,0 +15352,0 +15353,0 +15354,0 +15355,0 +15356,0 +15357,0 +15358,0 +15359,0 +15360,0 +15361,0 +15362,0 +15363,0 +15364,0 +15365,0 +15366,0 +15367,0 +15368,0 +15369,0 +15370,0 +15371,0 +15372,0 +15373,0 +15374,0 +15375,0 +15376,0 +15377,0 +15378,0 +15379,0 +15380,0 +15381,0 +15382,0 +15383,0 +15384,0 +15385,0 +15386,0 +15387,0 +15388,0 +15389,0 +15390,0 +15391,0 +15392,0 +15393,0 +15394,0 +15395,0 +15396,0 +15397,0 +15398,0 +15399,0 +15400,0 +15401,0 +15402,0 +15403,0 +15404,0 +15405,0 +15406,0 +15407,0 +15408,0 +15409,0 +15410,0 +15411,0 +15412,0 +15413,0 +15414,0 +15415,0 +15416,0 +15417,0 +15418,0 +15419,0 +15420,0 +15421,0 +15422,0 +15423,0 +15424,0 +15425,0 +15426,0 +15427,0 +15428,0 +15429,0 +15430,0 +15431,0 +15432,0 +15433,0 +15434,0 +15435,0 +15436,0 +15437,0 +15438,0 +15439,0 +15440,0 +15441,0 +15442,0 +15443,0 +15444,0 +15445,0 +15446,0 +15447,0 +15448,0 +15449,0 +15450,0 +15451,0 +15452,0 +15453,0 +15454,0 +15455,0 +15456,0 +15457,0 +15458,0 +15459,0 +15460,0 +15461,0 +15462,0 +15463,0 +15464,0 +15465,0 +15466,0 +15467,0 +15468,0 +15469,0 +15470,0 +15471,0 +15472,0 +15473,0 +15474,0 +15475,0 +15476,0 +15477,0 +15478,0 +15479,0 +15480,0 +15481,0 +15482,0 +15483,0 +15484,0 +15485,0 +15486,0 +15487,0 +15488,0 +15489,0 +15490,0 +15491,0 +15492,0 +15493,0 +15494,0 +15495,0 +15496,0 +15497,0 +15498,0 +15499,0 +15500,0 +15501,0 +15502,0 +15503,0 +15504,0 +15505,0 +15506,0 +15507,0 +15508,0 +15509,0 +15510,0 +15511,0 +15512,0 +15513,0 +15514,0 +15515,0 +15516,0 +15517,0 +15518,0 +15519,0 +15520,0 +15521,0 +15522,0 +15523,0 +15524,0 +15525,0 +15526,0 +15527,0 +15528,0 +15529,0 +15530,0 +15531,0 +15532,0 +15533,0 +15534,0 +15535,0 +15536,0 +15537,0 +15538,0 +15539,0 +15540,0 +15541,0 +15542,0 +15543,0 +15544,0 +15545,0 +15546,0 +15547,0 +15548,0 +15549,0 +15550,0 +15551,0 +15552,0 +15553,0 +15554,0 +15555,0 +15556,0 +15557,0 +15558,0 +15559,0 +15560,0 +15561,0 +15562,0 +15563,0 +15564,0 +15565,0 +15566,0 +15567,0 +15568,0 +15569,0 +15570,0 +15571,0 +15572,0 +15573,0 +15574,0 +15575,0 +15576,0 +15577,0 +15578,0 +15579,0 +15580,0 +15581,0 +15582,0 +15583,0 +15584,0 +15585,0 +15586,0 +15587,0 +15588,0 +15589,0 +15590,0 +15591,0 +15592,0 +15593,0 +15594,0 +15595,0 +15596,0 +15597,0 +15598,0 +15599,0 +15600,0 +15601,0 +15602,0 +15603,0 +15604,0 +15605,0 +15606,0 +15607,0 +15608,0 +15609,0 +15610,0 +15611,0 +15612,0 +15613,0 +15614,0 +15615,0 +15616,0 +15617,0 +15618,0 +15619,0 +15620,0 +15621,0 +15622,0 +15623,0 +15624,0 +15625,0 +15626,0 +15627,0 +15628,0 +15629,0 +15630,0 +15631,0 +15632,0 +15633,0 +15634,0 +15635,0 +15636,0 +15637,0 +15638,0 +15639,0 +15640,0 +15641,0 +15642,0 +15643,0 +15644,0 +15645,0 +15646,0 +15647,0 +15648,0 +15649,0 +15650,0 +15651,0 +15652,0 +15653,0 +15654,0 +15655,0 +15656,0 +15657,0 +15658,0 +15659,0 +15660,0 +15661,0 +15662,0 +15663,0 +15664,0 +15665,0 +15666,0 +15667,0 +15668,0 +15669,0 +15670,0 +15671,0 +15672,0 +15673,0 +15674,0 +15675,0 +15676,0 +15677,0 +15678,0 +15679,0 +15680,0 +15681,0 +15682,0 +15683,0 +15684,0 +15685,0 +15686,0 +15687,0 +15688,0 +15689,0 +15690,0 +15691,0 +15692,0 +15693,0 +15694,0 +15695,0 +15696,0 +15697,0 +15698,0 +15699,0 +15700,0 +15701,0 +15702,0 +15703,0 +15704,0 +15705,0 +15706,0 +15707,0 +15708,0 +15709,0 +15710,0 +15711,0 +15712,0 +15713,0 +15714,0 +15715,0 +15716,0 +15717,0 +15718,0 +15719,0 +15720,0 +15721,0 +15722,0 +15723,0 +15724,0 +15725,0 +15726,0 +15727,0 +15728,0 +15729,0 +15730,0 +15731,0 +15732,0 +15733,0 +15734,0 +15735,0 +15736,0 +15737,0 +15738,0 +15739,0 +15740,0 +15741,0 +15742,0 +15743,0 +15744,0 +15745,0 +15746,0 +15747,0 +15748,0 +15749,0 +15750,0 +15751,0 +15752,0 +15753,0 +15754,0 +15755,0 +15756,0 +15757,0 +15758,0 +15759,0 +15760,0 +15761,0 +15762,0 +15763,0 +15764,0 +15765,0 +15766,0 +15767,0 +15768,0 +15769,0 +15770,0 +15771,0 +15772,0 +15773,0 +15774,0 +15775,0 +15776,0 +15777,0 +15778,0 +15779,0 +15780,0 +15781,0 +15782,0 +15783,0 +15784,0 +15785,0 +15786,0 +15787,0 +15788,0 +15789,0 +15790,0 +15791,0 +15792,0 +15793,0 +15794,0 +15795,0 +15796,0 +15797,0 +15798,0 +15799,0 +15800,0 +15801,0 +15802,0 +15803,0 +15804,0 +15805,0 +15806,0 +15807,0 +15808,0 +15809,0 +15810,0 +15811,0 +15812,0 +15813,0 +15814,0 +15815,0 +15816,0 +15817,0 +15818,0 +15819,0 +15820,0 +15821,0 +15822,0 +15823,0 +15824,0 +15825,0 +15826,0 +15827,0 +15828,0 +15829,0 +15830,0 +15831,0 +15832,0 +15833,0 +15834,0 +15835,0 +15836,0 +15837,0 +15838,0 +15839,0 +15840,0 +15841,0 +15842,0 +15843,0 +15844,0 +15845,0 +15846,0 +15847,0 +15848,0 +15849,0 +15850,0 +15851,0 +15852,0 +15853,0 +15854,0 +15855,0 +15856,0 +15857,0 +15858,0 +15859,0 +15860,0 +15861,0 +15862,0 +15863,0 +15864,0 +15865,0 +15866,0 +15867,0 +15868,0 +15869,0 +15870,0 +15871,0 +15872,0 +15873,0 +15874,0 +15875,0 +15876,0 +15877,0 +15878,0 +15879,0 +15880,0 +15881,0 +15882,0 +15883,0 +15884,0 +15885,0 +15886,0 +15887,0 +15888,0 +15889,0 +15890,0 +15891,0 +15892,0 +15893,0 +15894,0 +15895,0 +15896,0 +15897,0 +15898,0 +15899,0 +15900,0 +15901,0 +15902,0 +15903,0 +15904,0 +15905,0 +15906,0 +15907,0 +15908,0 +15909,0 +15910,0 +15911,0 +15912,0 +15913,0 +15914,0 +15915,0 +15916,0 +15917,0 +15918,0 +15919,0 +15920,0 +15921,0 +15922,0 +15923,0 +15924,0 +15925,0 +15926,0 +15927,0 +15928,0 +15929,0 +15930,0 +15931,0 +15932,0 +15933,0 +15934,0 +15935,0 +15936,0 +15937,0 +15938,0 +15939,0 +15940,0 +15941,0 +15942,0 +15943,0 +15944,0 +15945,0 +15946,0 +15947,0 +15948,0 +15949,0 +15950,0 +15951,0 +15952,0 +15953,0 +15954,0 +15955,0 +15956,0 +15957,0 +15958,0 +15959,0 +15960,0 +15961,0 +15962,0 +15963,0 +15964,0 +15965,0 +15966,0 +15967,0 +15968,0 +15969,0 +15970,0 +15971,0 +15972,0 +15973,0 +15974,0 +15975,0 +15976,0 +15977,0 +15978,0 +15979,0 +15980,0 +15981,0 +15982,0 +15983,0 +15984,0 +15985,0 +15986,0 +15987,0 +15988,0 +15989,0 +15990,0 +15991,0 +15992,0 +15993,0 +15994,0 +15995,0 +15996,0 +15997,0 +15998,0 +15999,0 +16000,0 +16001,0 +16002,0 +16003,0 +16004,0 +16005,0 +16006,0 +16007,0 +16008,0 +16009,0 +16010,0 +16011,0 +16012,0 +16013,0 +16014,0 +16015,0 +16016,0 +16017,0 +16018,0 +16019,0 +16020,0 +16021,0 +16022,0 +16023,0 +16024,0 +16025,0 +16026,0 +16027,0 +16028,0 +16029,0 +16030,0 +16031,0 +16032,0 +16033,0 +16034,0 +16035,0 +16036,0 +16037,0 +16038,0 +16039,0 +16040,0 +16041,0 +16042,0 +16043,0 +16044,0 +16045,0 +16046,0 +16047,0 +16048,0 +16049,0 +16050,0 +16051,0 +16052,0 +16053,0 +16054,0 +16055,0 +16056,0 +16057,0 +16058,0 +16059,0 +16060,0 +16061,0 +16062,0 +16063,0 +16064,0 +16065,0 +16066,0 +16067,0 +16068,0 +16069,0 +16070,0 +16071,0 +16072,0 +16073,0 +16074,0 +16075,0 +16076,0 +16077,0 +16078,0 +16079,0 +16080,0 +16081,0 +16082,0 +16083,0 +16084,0 +16085,0 +16086,0 +16087,0 +16088,0 +16089,0 +16090,0 +16091,0 +16092,0 +16093,0 +16094,0 +16095,0 +16096,0 +16097,0 +16098,0 +16099,0 +16100,0 +16101,0 +16102,0 +16103,0 +16104,0 +16105,0 +16106,0 +16107,0 +16108,0 +16109,0 +16110,0 +16111,0 +16112,0 +16113,0 +16114,0 +16115,0 +16116,0 +16117,0 +16118,0 +16119,0 +16120,0 +16121,0 +16122,0 +16123,0 +16124,0 +16125,0 +16126,0 +16127,0 +16128,0 +16129,0 +16130,0 +16131,0 +16132,0 +16133,0 +16134,0 +16135,0 +16136,0 +16137,0 +16138,0 +16139,0 +16140,0 +16141,0 +16142,0 +16143,0 +16144,0 +16145,0 +16146,0 +16147,0 +16148,0 +16149,0 +16150,0 +16151,0 +16152,0 +16153,0 +16154,0 +16155,0 +16156,0 +16157,0 +16158,0 +16159,0 +16160,0 +16161,0 +16162,0 +16163,0 +16164,0 +16165,0 +16166,0 +16167,0 +16168,0 +16169,0 +16170,0 +16171,0 +16172,0 +16173,0 +16174,0 +16175,0 +16176,0 +16177,0 +16178,0 +16179,0 +16180,0 +16181,0 +16182,0 +16183,0 +16184,0 +16185,0 +16186,0 +16187,0 +16188,0 +16189,0 +16190,0 +16191,0 +16192,0 +16193,0 +16194,0 +16195,0 +16196,0 +16197,0 +16198,0 +16199,0 +16200,0 +16201,0 +16202,0 +16203,0 +16204,0 +16205,0 +16206,0 +16207,0 +16208,0 +16209,0 +16210,0 +16211,0 +16212,0 +16213,0 +16214,0 +16215,0 +16216,0 +16217,0 +16218,0 +16219,0 +16220,0 +16221,0 +16222,0 +16223,0 +16224,0 +16225,0 +16226,0 +16227,0 +16228,0 +16229,0 +16230,0 +16231,0 +16232,0 +16233,0 +16234,0 +16235,0 +16236,0 +16237,0 +16238,0 +16239,0 +16240,0 +16241,0 +16242,0 +16243,0 +16244,0 +16245,0 +16246,0 +16247,0 +16248,0 +16249,0 +16250,0 +16251,0 +16252,0 +16253,0 +16254,0 +16255,0 +16256,0 +16257,0 +16258,0 +16259,0 +16260,0 +16261,0 +16262,0 +16263,0 +16264,0 +16265,0 +16266,0 +16267,0 +16268,0 +16269,0 +16270,0 +16271,0 +16272,0 +16273,0 +16274,0 +16275,0 +16276,0 +16277,0 +16278,0 +16279,0 +16280,0 +16281,0 +16282,0 +16283,0 +16284,0 +16285,0 +16286,0 +16287,0 +16288,0 +16289,0 +16290,0 +16291,0 +16292,0 +16293,0 +16294,0 +16295,0 +16296,0 +16297,0 +16298,0 +16299,0 +16300,0 +16301,0 +16302,0 +16303,0 +16304,0 +16305,0 +16306,0 +16307,0 +16308,0 +16309,0 +16310,0 +16311,0 +16312,0 +16313,0 +16314,0 +16315,0 +16316,0 +16317,0 +16318,0 +16319,0 +16320,0 +16321,0 +16322,0 +16323,0 +16324,0 +16325,0 +16326,0 +16327,0 +16328,0 +16329,0 +16330,0 +16331,0 +16332,0 +16333,0 +16334,0 +16335,0 +16336,0 +16337,0 +16338,0 +16339,0 +16340,0 +16341,0 +16342,0 +16343,0 +16344,0 +16345,0 +16346,0 +16347,0 +16348,0 +16349,0 +16350,0 +16351,0 +16352,0 +16353,0 +16354,0 +16355,0 +16356,0 +16357,0 +16358,0 +16359,0 +16360,0 +16361,0 +16362,0 +16363,0 +16364,0 +16365,0 +16366,0 +16367,0 +16368,0 +16369,0 +16370,0 +16371,0 +16372,0 +16373,0 +16374,0 +16375,0 +16376,0 +16377,0 +16378,0 +16379,0 +16380,0 +16381,0 +16382,0 +16383,0 +16384,0 +16385,0 +16386,0 +16387,0 +16388,0 +16389,0 +16390,0 +16391,0 +16392,0 +16393,0 +16394,0 +16395,0 +16396,0 +16397,0 +16398,0 +16399,0 +16400,0 +16401,0 +16402,0 +16403,0 +16404,0 +16405,0 +16406,0 +16407,0 +16408,0 +16409,0 +16410,0 +16411,0 +16412,0 +16413,0 +16414,0 +16415,0 +16416,0 +16417,0 +16418,0 +16419,0 +16420,0 +16421,0 +16422,0 +16423,0 +16424,0 +16425,0 +16426,0 +16427,0 +16428,0 +16429,0 +16430,0 +16431,0 +16432,0 +16433,0 +16434,0 +16435,0 +16436,0 +16437,0 +16438,0 +16439,0 +16440,0 +16441,0 +16442,0 +16443,0 +16444,0 +16445,0 +16446,0 +16447,0 +16448,0 +16449,0 +16450,0 +16451,0 +16452,0 +16453,0 +16454,0 +16455,0 +16456,0 +16457,0 +16458,0 +16459,0 +16460,0 +16461,0 +16462,0 +16463,0 +16464,0 +16465,0 +16466,0 +16467,0 +16468,0 +16469,0 +16470,0 +16471,0 +16472,0 +16473,0 +16474,0 +16475,0 +16476,0 +16477,0 +16478,0 +16479,0 +16480,0 +16481,0 +16482,0 +16483,0 +16484,0 +16485,0 +16486,0 +16487,0 +16488,0 +16489,0 +16490,0 +16491,0 +16492,0 +16493,0 +16494,0 +16495,0 +16496,0 +16497,0 +16498,0 +16499,0 +16500,0 +16501,0 +16502,0 +16503,0 +16504,0 +16505,0 +16506,0 +16507,0 +16508,0 +16509,0 +16510,0 +16511,0 +16512,0 +16513,0 +16514,0 +16515,0 +16516,0 +16517,0 +16518,0 +16519,0 +16520,0 +16521,0 +16522,0 +16523,0 +16524,0 +16525,0 +16526,0 +16527,0 +16528,0 +16529,0 +16530,0 +16531,0 +16532,0 +16533,0 +16534,0 +16535,0 +16536,0 +16537,0 +16538,0 +16539,0 +16540,0 +16541,0 +16542,0 +16543,0 +16544,0 +16545,0 +16546,0 +16547,0 +16548,0 +16549,0 +16550,0 +16551,0 +16552,0 +16553,0 +16554,0 +16555,0 +16556,0 +16557,0 +16558,0 +16559,0 +16560,0 +16561,0 +16562,0 +16563,0 +16564,0 +16565,0 +16566,0 +16567,0 +16568,0 +16569,0 +16570,0 +16571,0 +16572,0 +16573,0 +16574,0 +16575,0 +16576,0 +16577,0 +16578,0 +16579,0 +16580,0 +16581,0 +16582,0 +16583,0 +16584,0 +16585,0 +16586,0 +16587,0 +16588,0 +16589,0 +16590,0 +16591,0 +16592,0 +16593,0 +16594,0 +16595,0 +16596,0 +16597,0 +16598,0 +16599,0 +16600,0 +16601,0 +16602,0 +16603,0 +16604,0 +16605,0 +16606,0 +16607,0 +16608,0 +16609,0 +16610,0 +16611,0 +16612,0 +16613,0 +16614,0 +16615,0 +16616,0 +16617,0 +16618,0 +16619,0 +16620,0 +16621,0 +16622,0 +16623,0 +16624,0 +16625,0 +16626,0 +16627,0 +16628,0 +16629,0 +16630,0 +16631,0 +16632,0 +16633,0 +16634,0 +16635,0 +16636,0 +16637,0 +16638,0 +16639,0 +16640,0 +16641,0 +16642,0 +16643,0 +16644,0 +16645,0 +16646,0 +16647,0 +16648,0 +16649,0 +16650,0 +16651,0 +16652,0 +16653,0 +16654,0 +16655,0 +16656,0 +16657,0 +16658,0 +16659,0 +16660,0 +16661,0 +16662,0 +16663,0 +16664,0 +16665,0 +16666,0 +16667,0 +16668,0 +16669,0 +16670,0 +16671,0 +16672,0 +16673,0 +16674,0 +16675,0 +16676,0 +16677,0 +16678,0 +16679,0 +16680,0 +16681,0 +16682,0 +16683,0 +16684,0 +16685,0 +16686,0 +16687,0 +16688,0 +16689,0 +16690,0 +16691,0 +16692,0 +16693,0 +16694,0 +16695,0 +16696,0 +16697,0 +16698,0 +16699,0 +16700,0 +16701,0 +16702,0 +16703,0 +16704,0 +16705,0 +16706,0 +16707,0 +16708,0 +16709,0 +16710,0 +16711,0 +16712,0 +16713,0 +16714,0 +16715,0 +16716,0 +16717,0 +16718,0 +16719,0 +16720,0 +16721,0 +16722,0 +16723,0 +16724,0 +16725,0 +16726,0 +16727,0 +16728,0 +16729,0 +16730,0 +16731,0 +16732,0 +16733,0 +16734,0 +16735,0 +16736,0 +16737,0 +16738,0 +16739,0 +16740,0 +16741,0 +16742,0 +16743,0 +16744,0 +16745,0 +16746,0 +16747,0 +16748,0 +16749,0 +16750,0 +16751,0 +16752,0 +16753,0 +16754,0 +16755,0 +16756,0 +16757,0 +16758,0 +16759,0 +16760,0 +16761,0 +16762,0 +16763,0 +16764,0 +16765,0 +16766,0 +16767,0 +16768,0 +16769,0 +16770,0 +16771,0 +16772,0 +16773,0 +16774,0 +16775,0 +16776,0 +16777,0 +16778,0 +16779,0 +16780,0 +16781,0 +16782,0 +16783,0 +16784,0 +16785,0 +16786,0 +16787,0 +16788,0 +16789,0 +16790,0 +16791,0 +16792,0 +16793,0 +16794,0 +16795,0 +16796,0 +16797,0 +16798,0 +16799,0 +16800,0 +16801,0 +16802,0 +16803,0 +16804,0 +16805,0 +16806,0 +16807,0 +16808,0 +16809,0 +16810,0 +16811,0 +16812,0 +16813,0 +16814,0 +16815,0 +16816,0 +16817,0 +16818,0 +16819,0 +16820,0 +16821,0 +16822,0 +16823,0 +16824,0 +16825,0 +16826,0 +16827,0 +16828,0 +16829,0 +16830,0 +16831,0 +16832,0 +16833,0 +16834,0 +16835,0 +16836,0 +16837,0 +16838,0 +16839,0 +16840,0 +16841,0 +16842,0 +16843,0 +16844,0 +16845,0 +16846,0 +16847,0 +16848,0 +16849,0 +16850,0 +16851,0 +16852,0 +16853,0 +16854,0 +16855,0 +16856,0 +16857,0 +16858,0 +16859,0 +16860,0 +16861,0 +16862,0 +16863,0 +16864,0 +16865,0 +16866,0 +16867,0 +16868,0 +16869,0 +16870,0 +16871,0 +16872,0 +16873,0 +16874,0 +16875,0 +16876,0 +16877,0 +16878,0 +16879,0 +16880,0 +16881,0 +16882,0 +16883,0 +16884,0 +16885,0 +16886,0 +16887,0 +16888,0 +16889,0 +16890,0 +16891,0 +16892,0 +16893,0 +16894,0 +16895,0 +16896,0 +16897,0 +16898,0 +16899,0 +16900,0 +16901,0 +16902,0 +16903,0 +16904,0 +16905,0 +16906,0 +16907,0 +16908,0 +16909,0 +16910,0 +16911,0 +16912,0 +16913,0 +16914,0 +16915,0 +16916,0 +16917,0 +16918,0 +16919,0 +16920,0 +16921,0 +16922,0 +16923,0 +16924,0 +16925,0 +16926,0 +16927,0 +16928,0 +16929,0 +16930,0 +16931,0 +16932,0 +16933,0 +16934,0 +16935,0 +16936,0 +16937,0 +16938,0 +16939,0 +16940,0 +16941,0 +16942,0 +16943,0 +16944,0 +16945,0 +16946,0 +16947,0 +16948,0 +16949,0 +16950,0 +16951,0 +16952,0 +16953,0 +16954,0 +16955,0 +16956,0 +16957,0 +16958,0 +16959,0 +16960,0 +16961,0 +16962,0 +16963,0 +16964,0 +16965,0 +16966,0 +16967,0 +16968,0 +16969,0 +16970,0 +16971,0 +16972,0 +16973,0 +16974,0 +16975,0 +16976,0 +16977,0 +16978,0 +16979,0 +16980,0 +16981,0 +16982,0 +16983,0 +16984,0 +16985,0 +16986,0 +16987,0 +16988,0 +16989,0 +16990,0 +16991,0 +16992,0 +16993,0 +16994,0 +16995,0 +16996,0 +16997,0 +16998,0 +16999,0 +17000,0 +17001,0 +17002,0 +17003,0 +17004,0 +17005,0 +17006,0 +17007,0 +17008,0 +17009,0 +17010,0 +17011,0 +17012,0 +17013,0 +17014,0 +17015,0 +17016,0 +17017,0 +17018,0 +17019,0 +17020,0 +17021,0 +17022,0 +17023,0 +17024,0 +17025,0 +17026,0 +17027,0 +17028,0 +17029,0 +17030,0 +17031,0 +17032,0 +17033,0 +17034,0 +17035,0 +17036,0 +17037,0 +17038,0 +17039,0 +17040,0 +17041,0 +17042,0 +17043,0 +17044,0 +17045,0 +17046,0 +17047,0 +17048,0 +17049,0 +17050,0 +17051,0 +17052,0 +17053,0 +17054,0 +17055,0 +17056,0 +17057,0 +17058,0 +17059,0 +17060,0 +17061,0 +17062,0 +17063,0 +17064,0 +17065,0 +17066,0 +17067,0 +17068,0 +17069,0 +17070,0 +17071,0 +17072,0 +17073,0 +17074,0 +17075,0 +17076,0 +17077,0 +17078,0 +17079,0 +17080,0 +17081,0 +17082,0 +17083,0 +17084,0 +17085,0 +17086,0 +17087,0 +17088,0 +17089,0 +17090,0 +17091,0 +17092,0 +17093,0 +17094,0 +17095,0 +17096,0 +17097,0 +17098,0 +17099,0 +17100,0 +17101,0 +17102,0 +17103,0 +17104,0 +17105,0 +17106,0 +17107,0 +17108,0 +17109,0 +17110,0 +17111,0 +17112,0 +17113,0 +17114,0 +17115,0 +17116,0 +17117,0 +17118,0 +17119,0 +17120,0 +17121,0 +17122,0 +17123,0 +17124,0 +17125,0 +17126,0 +17127,0 +17128,0 +17129,0 +17130,0 +17131,0 +17132,0 +17133,0 +17134,0 +17135,0 +17136,0 +17137,0 +17138,0 +17139,0 +17140,0 +17141,0 +17142,0 +17143,0 +17144,0 +17145,0 +17146,0 +17147,0 +17148,0 +17149,0 +17150,0 +17151,0 +17152,0 +17153,0 +17154,0 +17155,0 +17156,0 +17157,0 +17158,0 +17159,0 +17160,0 +17161,0 +17162,0 +17163,0 +17164,0 +17165,0 +17166,0 +17167,0 +17168,0 +17169,0 +17170,0 +17171,0 +17172,0 +17173,0 +17174,0 +17175,0 +17176,0 +17177,0 +17178,0 +17179,0 +17180,0 +17181,0 +17182,0 +17183,0 +17184,0 +17185,0 +17186,0 +17187,0 +17188,0 +17189,0 +17190,0 +17191,0 +17192,0 +17193,0 +17194,0 +17195,0 +17196,0 +17197,0 +17198,0 +17199,0 +17200,0 +17201,0 +17202,0 +17203,0 +17204,0 +17205,0 +17206,0 +17207,0 +17208,0 +17209,0 +17210,0 +17211,0 +17212,0 +17213,0 +17214,0 +17215,0 +17216,0 +17217,0 +17218,0 +17219,0 +17220,0 +17221,0 +17222,0 +17223,0 +17224,0 +17225,0 +17226,0 +17227,0 +17228,0 +17229,0 +17230,0 +17231,0 +17232,0 +17233,0 +17234,0 +17235,0 +17236,0 +17237,0 +17238,0 +17239,0 +17240,0 +17241,0 +17242,0 +17243,0 +17244,0 +17245,0 +17246,0 +17247,0 +17248,0 +17249,0 +17250,0 +17251,0 +17252,0 +17253,0 +17254,0 +17255,0 +17256,0 +17257,0 +17258,0 +17259,0 +17260,0 +17261,0 +17262,0 +17263,0 +17264,0 +17265,0 +17266,0 +17267,0 +17268,0 +17269,0 +17270,0 +17271,0 +17272,0 +17273,0 +17274,0 +17275,0 +17276,0 +17277,0 +17278,0 +17279,0 +17280,0 +17281,0 +17282,0 +17283,0 +17284,0 +17285,0 +17286,0 +17287,0 +17288,0 +17289,0 +17290,0 +17291,0 +17292,0 +17293,0 +17294,0 +17295,0 +17296,0 +17297,0 +17298,0 +17299,0 +17300,0 +17301,0 +17302,0 +17303,0 +17304,0 +17305,0 +17306,0 +17307,0 +17308,0 +17309,0 +17310,0 +17311,0 +17312,0 +17313,0 +17314,0 +17315,0 +17316,0 +17317,0 +17318,0 +17319,0 +17320,0 +17321,0 +17322,0 +17323,0 +17324,0 +17325,0 +17326,0 +17327,0 +17328,0 +17329,0 +17330,0 +17331,0 +17332,0 +17333,0 +17334,0 +17335,0 +17336,0 +17337,0 +17338,0 +17339,0 +17340,0 +17341,0 +17342,0 +17343,0 +17344,0 +17345,0 +17346,0 +17347,0 +17348,0 +17349,0 +17350,0 +17351,0 +17352,0 +17353,0 +17354,0 +17355,0 +17356,0 +17357,0 +17358,0 +17359,0 +17360,0 +17361,0 +17362,0 +17363,0 +17364,0 +17365,0 +17366,0 +17367,0 +17368,0 +17369,0 +17370,0 +17371,0 +17372,0 +17373,0 +17374,0 +17375,0 +17376,0 +17377,0 +17378,0 +17379,0 +17380,0 +17381,0 +17382,0 +17383,0 +17384,0 +17385,0 +17386,0 +17387,0 +17388,0 +17389,0 +17390,0 +17391,0 +17392,0 +17393,0 +17394,0 +17395,0 +17396,0 +17397,0 +17398,0 +17399,0 +17400,0 +17401,0 +17402,0 +17403,0 +17404,0 +17405,0 +17406,0 +17407,0 +17408,0 +17409,0 +17410,0 +17411,0 +17412,0 +17413,0 +17414,0 +17415,0 +17416,0 +17417,0 +17418,0 +17419,0 +17420,0 +17421,0 +17422,0 +17423,0 +17424,0 +17425,0 +17426,0 +17427,0 +17428,0 +17429,0 +17430,0 +17431,0 +17432,0 +17433,0 +17434,0 +17435,0 +17436,0 +17437,0 +17438,0 +17439,0 +17440,0 +17441,0 +17442,0 +17443,0 +17444,0 +17445,0 +17446,0 +17447,0 +17448,0 +17449,0 +17450,0 +17451,0 +17452,0 +17453,0 +17454,0 +17455,0 +17456,0 +17457,0 +17458,0 +17459,0 +17460,0 +17461,0 +17462,0 +17463,0 +17464,0 +17465,0 +17466,0 +17467,0 +17468,0 +17469,0 +17470,0 +17471,0 +17472,0 +17473,0 +17474,0 +17475,0 +17476,0 +17477,0 +17478,0 +17479,0 +17480,0 +17481,0 +17482,0 +17483,0 +17484,0 +17485,0 +17486,0 +17487,0 +17488,0 +17489,0 +17490,0 +17491,0 +17492,0 +17493,0 +17494,0 +17495,0 +17496,0 +17497,0 +17498,0 +17499,0 +17500,0 +17501,0 +17502,0 +17503,0 +17504,0 +17505,0 +17506,0 +17507,0 +17508,0 +17509,0 +17510,0 +17511,0 +17512,0 +17513,0 +17514,0 +17515,0 +17516,0 +17517,0 +17518,0 +17519,0 +17520,0 +17521,0 +17522,0 +17523,0 +17524,0 +17525,0 +17526,0 +17527,0 +17528,0 +17529,0 +17530,0 +17531,0 +17532,0 +17533,0 +17534,0 +17535,0 +17536,0 +17537,0 +17538,0 +17539,0 +17540,0 +17541,0 +17542,0 +17543,0 +17544,0 +17545,0 +17546,0 +17547,0 +17548,0 +17549,0 +17550,0 +17551,0 +17552,0 +17553,0 +17554,0 +17555,0 +17556,0 +17557,0 +17558,0 +17559,0 +17560,0 +17561,0 +17562,0 +17563,0 +17564,0 +17565,0 +17566,0 +17567,0 +17568,0 +17569,0 +17570,0 +17571,0 +17572,0 +17573,0 +17574,0 +17575,0 +17576,0 +17577,0 +17578,0 +17579,0 +17580,0 +17581,0 +17582,0 +17583,0 +17584,0 +17585,0 +17586,0 +17587,0 +17588,0 +17589,0 +17590,0 +17591,0 +17592,0 +17593,0 +17594,0 +17595,0 +17596,0 +17597,0 +17598,0 +17599,0 +17600,0 +17601,0 +17602,0 +17603,0 +17604,0 +17605,0 +17606,0 +17607,0 +17608,0 +17609,0 +17610,0 +17611,0 +17612,0 +17613,0 +17614,0 +17615,0 +17616,0 +17617,0 +17618,0 +17619,0 +17620,0 +17621,0 +17622,0 +17623,0 +17624,0 +17625,0 +17626,0 +17627,0 +17628,0 +17629,0 +17630,0 +17631,0 +17632,0 +17633,0 +17634,0 +17635,0 +17636,0 +17637,0 +17638,0 +17639,0 +17640,0 +17641,0 +17642,0 +17643,0 +17644,0 +17645,0 +17646,0 +17647,0 +17648,0 +17649,0 +17650,0 +17651,0 +17652,0 +17653,0 +17654,0 +17655,0 +17656,0 +17657,0 +17658,0 +17659,0 +17660,0 +17661,0 +17662,0 +17663,0 +17664,0 +17665,0 +17666,0 +17667,0 +17668,0 +17669,0 +17670,0 +17671,0 +17672,0 +17673,0 +17674,0 +17675,0 +17676,0 +17677,0 +17678,0 +17679,0 +17680,0 +17681,0 +17682,0 +17683,0 +17684,0 +17685,0 +17686,0 +17687,0 +17688,0 +17689,0 +17690,0 +17691,0 +17692,0 +17693,0 +17694,0 +17695,0 +17696,0 +17697,0 +17698,0 +17699,0 +17700,0 +17701,0 +17702,0 +17703,0 +17704,0 +17705,0 +17706,0 +17707,0 +17708,0 +17709,0 +17710,0 +17711,0 +17712,0 +17713,0 +17714,0 +17715,0 +17716,0 +17717,0 +17718,0 +17719,0 +17720,0 +17721,0 +17722,0 +17723,0 +17724,0 +17725,0 +17726,0 +17727,0 +17728,0 +17729,0 +17730,0 +17731,0 +17732,0 +17733,0 +17734,0 +17735,0 +17736,0 +17737,0 +17738,0 +17739,0 +17740,0 +17741,0 +17742,0 +17743,0 +17744,0 +17745,0 +17746,0 +17747,0 +17748,0 +17749,0 +17750,0 +17751,0 +17752,0 +17753,0 +17754,0 +17755,0 +17756,0 +17757,0 +17758,0 +17759,0 +17760,0 +17761,0 +17762,0 +17763,0 +17764,0 +17765,0 +17766,0 +17767,0 +17768,0 +17769,0 +17770,0 +17771,0 +17772,0 +17773,0 +17774,0 +17775,0 +17776,0 +17777,0 +17778,0 +17779,0 +17780,0 +17781,0 +17782,0 +17783,0 +17784,0 +17785,0 +17786,0 +17787,0 +17788,0 +17789,0 +17790,0 +17791,0 +17792,0 +17793,0 +17794,0 +17795,0 +17796,0 +17797,0 +17798,0 +17799,0 +17800,0 +17801,0 +17802,0 +17803,0 +17804,0 +17805,0 +17806,0 +17807,0 +17808,0 +17809,0 +17810,0 +17811,0 +17812,0 +17813,0 +17814,0 +17815,0 +17816,0 +17817,0 +17818,0 +17819,0 +17820,0 +17821,0 +17822,0 +17823,0 +17824,0 +17825,0 +17826,0 +17827,0 +17828,0 +17829,0 +17830,0 +17831,0 +17832,0 +17833,0 +17834,0 +17835,0 +17836,0 +17837,0 +17838,0 +17839,0 +17840,0 +17841,0 +17842,0 +17843,0 +17844,0 +17845,0 +17846,0 +17847,0 +17848,0 +17849,0 +17850,0 +17851,0 +17852,0 +17853,0 +17854,0 +17855,0 +17856,0 +17857,0 +17858,0 +17859,0 +17860,0 +17861,0 +17862,0 +17863,0 +17864,0 +17865,0 +17866,0 +17867,0 +17868,0 +17869,0 +17870,0 +17871,0 +17872,0 +17873,0 +17874,0 +17875,0 +17876,0 +17877,0 +17878,0 +17879,0 +17880,0 +17881,0 +17882,0 +17883,0 +17884,0 +17885,0 +17886,0 +17887,0 +17888,0 +17889,0 +17890,0 +17891,0 +17892,0 +17893,0 +17894,0 +17895,0 +17896,0 +17897,0 +17898,0 +17899,0 +17900,0 +17901,0 +17902,0 +17903,0 +17904,0 +17905,0 +17906,0 +17907,0 +17908,0 +17909,0 +17910,0 +17911,0 +17912,0 +17913,0 +17914,0 +17915,0 +17916,0 +17917,0 +17918,0 +17919,0 +17920,0 +17921,0 +17922,0 +17923,0 +17924,0 +17925,0 +17926,0 +17927,0 +17928,0 +17929,0 +17930,0 +17931,0 +17932,0 +17933,0 +17934,0 +17935,0 +17936,0 +17937,0 +17938,0 +17939,0 +17940,0 +17941,0 +17942,0 +17943,0 +17944,0 +17945,0 +17946,0 +17947,0 +17948,0 +17949,0 +17950,0 +17951,0 +17952,0 +17953,0 +17954,0 +17955,0 +17956,0 +17957,0 +17958,0 +17959,0 +17960,0 +17961,0 +17962,0 +17963,0 +17964,0 +17965,0 +17966,0 +17967,0 +17968,0 +17969,0 +17970,0 +17971,0 +17972,0 +17973,0 +17974,0 +17975,0 +17976,0 +17977,0 +17978,0 +17979,0 +17980,0 +17981,0 +17982,0 +17983,0 +17984,0 +17985,0 +17986,0 +17987,0 +17988,0 +17989,0 +17990,0 +17991,0 +17992,0 +17993,0 +17994,0 +17995,0 +17996,0 +17997,0 +17998,0 +17999,0 +18000,0 +18001,0 +18002,0 +18003,0 +18004,0 +18005,0 +18006,0 +18007,0 +18008,0 +18009,0 +18010,0 +18011,0 +18012,0 +18013,0 +18014,0 +18015,0 +18016,0 +18017,0 +18018,0 +18019,0 +18020,0 +18021,0 +18022,0 +18023,0 +18024,0 +18025,0 +18026,0 +18027,0 +18028,0 +18029,0 +18030,0 +18031,0 +18032,0 +18033,0 +18034,0 +18035,0 +18036,0 +18037,0 +18038,0 +18039,0 +18040,0 +18041,0 +18042,0 +18043,0 +18044,0 +18045,0 +18046,0 +18047,0 +18048,0 +18049,0 +18050,0 +18051,0 +18052,0 +18053,0 +18054,0 +18055,0 +18056,0 +18057,0 +18058,0 +18059,0 +18060,0 +18061,0 +18062,0 +18063,0 +18064,0 +18065,0 +18066,0 +18067,0 +18068,0 +18069,0 +18070,0 +18071,0 +18072,0 +18073,0 +18074,0 +18075,0 +18076,0 +18077,0 +18078,0 +18079,0 +18080,0 +18081,0 +18082,0 +18083,0 +18084,0 +18085,0 +18086,0 +18087,0 +18088,0 +18089,0 +18090,0 +18091,0 +18092,0 +18093,0 +18094,0 +18095,0 +18096,0 +18097,0 +18098,0 +18099,0 +18100,0 +18101,0 +18102,0 +18103,0 +18104,0 +18105,0 +18106,0 +18107,0 +18108,0 +18109,0 +18110,0 +18111,0 +18112,0 +18113,0 +18114,0 +18115,0 +18116,0 +18117,0 +18118,0 +18119,0 +18120,0 +18121,0 +18122,0 +18123,0 +18124,0 +18125,0 +18126,0 +18127,0 +18128,0 +18129,0 +18130,0 +18131,0 +18132,0 +18133,0 +18134,0 +18135,0 +18136,0 +18137,0 +18138,0 +18139,0 +18140,0 +18141,0 +18142,0 +18143,0 +18144,0 +18145,0 +18146,0 +18147,0 +18148,0 +18149,0 +18150,0 +18151,0 +18152,0 +18153,0 +18154,0 +18155,0 +18156,0 +18157,0 +18158,0 +18159,0 +18160,0 +18161,0 +18162,0 +18163,0 +18164,0 +18165,0 +18166,0 +18167,0 +18168,0 +18169,0 +18170,0 +18171,0 +18172,0 +18173,0 +18174,0 +18175,0 +18176,0 +18177,0 +18178,0 +18179,0 +18180,0 +18181,0 +18182,0 +18183,0 +18184,0 +18185,0 +18186,0 +18187,0 +18188,0 +18189,0 +18190,0 +18191,0 +18192,0 +18193,0 +18194,0 +18195,0 +18196,0 +18197,0 +18198,0 +18199,0 +18200,0 +18201,0 +18202,0 +18203,0 +18204,0 +18205,0 +18206,0 +18207,0 +18208,0 +18209,0 +18210,0 +18211,0 +18212,0 +18213,0 +18214,0 +18215,0 +18216,0 +18217,0 +18218,0 +18219,0 +18220,0 +18221,0 +18222,0 +18223,0 +18224,0 +18225,0 +18226,0 +18227,0 +18228,0 +18229,0 +18230,0 +18231,0 +18232,0 +18233,0 +18234,0 +18235,0 +18236,0 +18237,0 +18238,0 +18239,0 +18240,0 +18241,0 +18242,0 +18243,0 +18244,0 +18245,0 +18246,0 +18247,0 +18248,0 +18249,0 +18250,0 +18251,0 +18252,0 +18253,0 +18254,0 +18255,0 +18256,0 +18257,0 +18258,0 +18259,0 +18260,0 +18261,0 +18262,0 +18263,0 +18264,0 +18265,0 +18266,0 +18267,0 +18268,0 +18269,0 +18270,0 +18271,0 +18272,0 +18273,0 +18274,0 +18275,0 +18276,0 +18277,0 +18278,0 +18279,0 +18280,0 +18281,0 +18282,0 +18283,0 +18284,0 +18285,0 +18286,0 +18287,0 +18288,0 +18289,0 +18290,0 +18291,0 +18292,0 +18293,0 +18294,0 +18295,0 +18296,0 +18297,0 +18298,0 +18299,0 +18300,0 +18301,0 +18302,0 +18303,0 +18304,0 +18305,0 +18306,0 +18307,0 +18308,0 +18309,0 +18310,0 +18311,0 +18312,0 +18313,0 +18314,0 +18315,0 +18316,0 +18317,0 +18318,0 +18319,0 +18320,0 +18321,0 +18322,0 +18323,0 +18324,0 +18325,0 +18326,0 +18327,0 +18328,0 +18329,0 +18330,0 +18331,0 +18332,0 +18333,0 +18334,0 +18335,0 +18336,0 +18337,0 +18338,0 +18339,0 +18340,0 +18341,0 +18342,0 +18343,0 +18344,0 +18345,0 +18346,0 +18347,0 +18348,0 +18349,0 +18350,0 +18351,0 +18352,0 +18353,0 +18354,0 +18355,0 +18356,0 +18357,0 +18358,0 +18359,0 +18360,0 +18361,0 +18362,0 +18363,0 +18364,0 +18365,0 +18366,0 +18367,0 +18368,0 +18369,0 +18370,0 +18371,0 +18372,0 +18373,0 +18374,0 +18375,0 +18376,0 +18377,0 +18378,0 +18379,0 +18380,0 +18381,0 +18382,0 +18383,0 +18384,0 +18385,0 +18386,0 +18387,0 +18388,0 +18389,0 +18390,0 +18391,0 +18392,0 +18393,0 +18394,0 +18395,0 +18396,0 +18397,0 +18398,0 +18399,0 +18400,0 +18401,0 +18402,0 +18403,0 +18404,0 +18405,0 +18406,0 +18407,0 +18408,0 +18409,0 +18410,0 +18411,0 +18412,0 +18413,0 +18414,0 +18415,0 +18416,0 +18417,0 +18418,0 +18419,0 +18420,0 +18421,0 +18422,0 +18423,0 +18424,0 +18425,0 +18426,0 +18427,0 +18428,0 +18429,0 +18430,0 +18431,0 +18432,0 +18433,0 +18434,0 +18435,0 +18436,0 +18437,0 +18438,0 +18439,0 +18440,0 +18441,0 +18442,0 +18443,0 +18444,0 +18445,0 +18446,0 +18447,0 +18448,0 +18449,0 +18450,0 +18451,0 +18452,0 +18453,0 +18454,0 +18455,0 +18456,0 +18457,0 +18458,0 +18459,0 +18460,0 +18461,0 +18462,0 +18463,0 +18464,0 +18465,0 +18466,0 +18467,0 +18468,0 +18469,0 +18470,0 +18471,0 +18472,0 +18473,0 +18474,0 +18475,0 +18476,0 +18477,0 +18478,0 +18479,0 +18480,0 +18481,0 +18482,0 +18483,0 +18484,0 +18485,0 +18486,0 +18487,0 +18488,0 +18489,0 +18490,0 +18491,0 +18492,0 +18493,0 +18494,0 +18495,0 +18496,0 +18497,0 +18498,0 +18499,0 +18500,0 +18501,0 +18502,0 +18503,0 +18504,0 +18505,0 +18506,0 +18507,0 +18508,0 +18509,0 +18510,0 +18511,0 +18512,0 +18513,0 +18514,0 +18515,0 +18516,0 +18517,0 +18518,0 +18519,0 +18520,0 +18521,0 +18522,0 +18523,0 +18524,0 +18525,0 +18526,0 +18527,0 +18528,0 +18529,0 +18530,0 +18531,0 +18532,0 +18533,0 +18534,0 +18535,0 +18536,0 +18537,0 +18538,0 +18539,0 +18540,0 +18541,0 +18542,0 +18543,0 +18544,0 +18545,0 +18546,0 +18547,0 +18548,0 +18549,0 +18550,0 +18551,0 +18552,0 +18553,0 +18554,0 +18555,0 +18556,0 +18557,0 +18558,0 +18559,0 +18560,0 +18561,0 +18562,0 +18563,0 +18564,0 +18565,0 +18566,0 +18567,0 +18568,0 +18569,0 +18570,0 +18571,0 +18572,0 +18573,0 +18574,0 +18575,0 +18576,0 +18577,0 +18578,0 +18579,0 +18580,0 +18581,0 +18582,0 +18583,0 +18584,0 +18585,0 +18586,0 +18587,0 +18588,0 +18589,0 +18590,0 +18591,0 +18592,0 +18593,0 +18594,0 +18595,0 +18596,0 +18597,0 +18598,0 +18599,0 +18600,0 +18601,0 +18602,0 +18603,0 +18604,0 +18605,0 +18606,0 +18607,0 +18608,0 +18609,0 +18610,0 +18611,0 +18612,0 +18613,0 +18614,0 +18615,0 +18616,0 +18617,0 +18618,0 +18619,0 +18620,0 +18621,0 +18622,0 +18623,0 +18624,0 +18625,0 +18626,0 +18627,0 +18628,0 +18629,0 +18630,0 +18631,0 +18632,0 +18633,0 +18634,0 +18635,0 +18636,0 +18637,0 +18638,0 +18639,0 +18640,0 +18641,0 +18642,0 +18643,0 +18644,0 +18645,0 +18646,0 +18647,0 +18648,0 +18649,0 +18650,0 +18651,0 +18652,0 +18653,0 +18654,0 +18655,0 +18656,0 +18657,0 +18658,0 +18659,0 +18660,0 +18661,0 +18662,0 +18663,0 +18664,0 +18665,0 +18666,0 +18667,0 +18668,0 +18669,0 +18670,0 +18671,0 +18672,0 +18673,0 +18674,0 +18675,0 +18676,0 +18677,0 +18678,0 +18679,0 +18680,0 +18681,0 +18682,0 +18683,0 +18684,0 +18685,0 +18686,0 +18687,0 +18688,0 +18689,0 +18690,0 +18691,0 +18692,0 +18693,0 +18694,0 +18695,0 +18696,0 +18697,0 +18698,0 +18699,0 +18700,0 +18701,0 +18702,0 +18703,0 +18704,0 +18705,0 +18706,0 +18707,0 +18708,0 +18709,0 +18710,0 +18711,0 +18712,0 +18713,0 +18714,0 +18715,0 +18716,0 +18717,0 +18718,0 +18719,0 +18720,0 +18721,0 +18722,0 +18723,0 +18724,0 +18725,0 +18726,0 +18727,0 +18728,0 +18729,0 +18730,0 +18731,0 +18732,0 +18733,0 +18734,0 +18735,0 +18736,0 +18737,0 +18738,0 +18739,0 +18740,0 +18741,0 +18742,0 +18743,0 +18744,0 +18745,0 +18746,0 +18747,0 +18748,0 +18749,0 +18750,0 +18751,0 +18752,0 +18753,0 +18754,0 +18755,0 +18756,0 +18757,0 +18758,0 +18759,0 +18760,0 +18761,0 +18762,0 +18763,0 +18764,0 +18765,0 +18766,0 +18767,0 +18768,0 +18769,0 +18770,0 +18771,0 +18772,0 +18773,0 +18774,0 +18775,0 +18776,0 +18777,0 +18778,0 +18779,0 +18780,0 +18781,0 +18782,0 +18783,0 +18784,0 +18785,0 +18786,0 +18787,0 +18788,0 +18789,0 +18790,0 +18791,0 +18792,0 +18793,0 +18794,0 +18795,0 +18796,0 +18797,0 +18798,0 +18799,0 +18800,0 +18801,0 +18802,0 +18803,0 +18804,0 +18805,0 +18806,0 +18807,0 +18808,0 +18809,0 +18810,0 +18811,0 +18812,0 +18813,0 +18814,0 +18815,0 +18816,0 +18817,0 +18818,0 +18819,0 +18820,0 +18821,0 +18822,0 +18823,0 +18824,0 +18825,0 +18826,0 +18827,0 +18828,0 +18829,0 +18830,0 +18831,0 +18832,0 +18833,0 +18834,0 +18835,0 +18836,0 +18837,0 +18838,0 +18839,0 +18840,0 +18841,0 +18842,0 +18843,0 +18844,0 +18845,0 +18846,0 +18847,0 +18848,0 +18849,0 +18850,0 +18851,0 +18852,0 +18853,0 +18854,0 +18855,0 +18856,0 +18857,0 +18858,0 +18859,0 +18860,0 +18861,0 +18862,0 +18863,0 +18864,0 +18865,0 +18866,0 +18867,0 +18868,0 +18869,0 +18870,0 +18871,0 +18872,0 +18873,0 +18874,0 +18875,0 +18876,0 +18877,0 +18878,0 +18879,0 +18880,0 +18881,0 +18882,0 +18883,0 +18884,0 +18885,0 +18886,0 +18887,0 +18888,0 +18889,0 +18890,0 +18891,0 +18892,0 +18893,0 +18894,0 +18895,0 +18896,0 +18897,0 +18898,0 +18899,0 +18900,0 +18901,0 +18902,0 +18903,0 +18904,0 +18905,0 +18906,0 +18907,0 +18908,0 +18909,0 +18910,0 +18911,0 +18912,0 +18913,0 +18914,0 +18915,0 +18916,0 +18917,0 +18918,0 +18919,0 +18920,0 +18921,0 +18922,0 +18923,0 +18924,0 +18925,0 +18926,0 +18927,0 +18928,0 +18929,0 +18930,0 +18931,0 +18932,0 +18933,0 +18934,0 +18935,0 +18936,0 +18937,0 +18938,0 +18939,0 +18940,0 +18941,0 +18942,0 +18943,0 +18944,0 +18945,0 +18946,0 +18947,0 +18948,0 +18949,0 +18950,0 +18951,0 +18952,0 +18953,0 +18954,0 +18955,0 +18956,0 +18957,0 +18958,0 +18959,0 +18960,0 +18961,0 +18962,0 +18963,0 +18964,0 +18965,0 +18966,0 +18967,0 +18968,0 +18969,0 +18970,0 +18971,0 +18972,0 +18973,0 +18974,0 +18975,0 +18976,0 +18977,0 +18978,0 +18979,0 +18980,0 +18981,0 +18982,0 +18983,0 +18984,0 +18985,0 +18986,0 +18987,0 +18988,0 +18989,0 +18990,0 +18991,0 +18992,0 +18993,0 +18994,0 +18995,0 +18996,0 +18997,0 +18998,0 +18999,0 +19000,0 +19001,0 +19002,0 +19003,0 +19004,0 +19005,0 +19006,0 +19007,0 +19008,0 +19009,0 +19010,0 +19011,0 +19012,0 +19013,0 +19014,0 +19015,0 +19016,0 +19017,0 +19018,0 +19019,0 +19020,0 +19021,0 +19022,0 +19023,0 +19024,0 +19025,0 +19026,0 +19027,0 +19028,0 +19029,0 +19030,0 +19031,0 +19032,0 +19033,0 +19034,0 +19035,0 +19036,0 +19037,0 +19038,0 +19039,0 +19040,0 +19041,0 +19042,0 +19043,0 +19044,0 +19045,0 +19046,0 +19047,0 +19048,0 +19049,0 +19050,0 +19051,0 +19052,0 +19053,0 +19054,0 +19055,0 +19056,0 +19057,0 +19058,0 +19059,0 +19060,0 +19061,0 +19062,0 +19063,0 +19064,0 +19065,0 +19066,0 +19067,0 +19068,0 +19069,0 +19070,0 +19071,0 +19072,0 +19073,0 +19074,0 +19075,0 +19076,0 +19077,0 +19078,0 +19079,0 +19080,0 +19081,0 +19082,0 +19083,0 +19084,0 +19085,0 +19086,0 +19087,0 +19088,0 +19089,0 +19090,0 +19091,0 +19092,0 +19093,0 +19094,0 +19095,0 +19096,0 +19097,0 +19098,0 +19099,0 +19100,0 +19101,0 +19102,0 +19103,0 +19104,0 +19105,0 +19106,0 +19107,0 +19108,0 +19109,0 +19110,0 +19111,0 +19112,0 +19113,0 +19114,0 +19115,0 +19116,0 +19117,0 +19118,0 +19119,0 +19120,0 +19121,0 +19122,0 +19123,0 +19124,0 +19125,0 +19126,0 +19127,0 +19128,0 +19129,0 +19130,0 +19131,0 +19132,0 +19133,0 +19134,0 +19135,0 +19136,0 +19137,0 +19138,0 +19139,0 +19140,0 +19141,0 +19142,0 +19143,0 +19144,0 +19145,0 +19146,0 +19147,0 +19148,0 +19149,0 +19150,0 +19151,0 +19152,0 +19153,0 +19154,0 +19155,0 +19156,0 +19157,0 +19158,0 +19159,0 +19160,0 +19161,0 +19162,0 +19163,0 +19164,0 +19165,0 +19166,0 +19167,0 +19168,0 +19169,0 +19170,0 +19171,0 +19172,0 +19173,0 +19174,0 +19175,0 +19176,0 +19177,0 +19178,0 +19179,0 +19180,0 +19181,0 +19182,0 +19183,0 +19184,0 +19185,0 +19186,0 +19187,0 +19188,0 +19189,0 +19190,0 +19191,0 +19192,0 +19193,0 +19194,0 +19195,0 +19196,0 +19197,0 +19198,0 +19199,0 +19200,0 +19201,0 +19202,0 +19203,0 +19204,0 +19205,0 +19206,0 +19207,0 +19208,0 +19209,0 +19210,0 +19211,0 +19212,0 +19213,0 +19214,0 +19215,0 +19216,0 +19217,0 +19218,0 +19219,0 +19220,0 +19221,0 +19222,0 +19223,0 +19224,0 +19225,0 +19226,0 +19227,0 +19228,0 +19229,0 +19230,0 +19231,0 +19232,0 +19233,0 +19234,0 +19235,0 +19236,0 +19237,0 +19238,0 +19239,0 +19240,0 +19241,0 +19242,0 +19243,0 +19244,0 +19245,0 +19246,0 +19247,0 +19248,0 +19249,0 +19250,0 +19251,0 +19252,0 +19253,0 +19254,0 +19255,0 +19256,0 +19257,0 +19258,0 +19259,0 +19260,0 +19261,0 +19262,0 +19263,0 +19264,0 +19265,0 +19266,0 +19267,0 +19268,0 +19269,0 +19270,0 +19271,0 +19272,0 +19273,0 +19274,0 +19275,0 +19276,0 +19277,0 +19278,0 +19279,0 +19280,0 +19281,0 +19282,0 +19283,0 +19284,0 +19285,0 +19286,0 +19287,0 +19288,0 +19289,0 +19290,0 +19291,0 +19292,0 +19293,0 +19294,0 +19295,0 +19296,0 +19297,0 +19298,0 +19299,0 +19300,0 +19301,0 +19302,0 +19303,0 +19304,0 +19305,0 +19306,0 +19307,0 +19308,0 +19309,0 +19310,0 +19311,0 +19312,0 +19313,0 +19314,0 +19315,0 +19316,0 +19317,0 +19318,0 +19319,0 +19320,0 +19321,0 +19322,0 +19323,0 +19324,0 +19325,0 +19326,0 +19327,0 +19328,0 +19329,0 +19330,0 +19331,0 +19332,0 +19333,0 +19334,0 +19335,0 +19336,0 +19337,0 +19338,0 +19339,0 +19340,0 +19341,0 +19342,0 +19343,0 +19344,0 +19345,0 +19346,0 +19347,0 +19348,0 +19349,0 +19350,0 +19351,0 +19352,0 +19353,0 +19354,0 +19355,0 +19356,0 +19357,0 +19358,0 +19359,0 +19360,0 +19361,0 +19362,0 +19363,0 +19364,0 +19365,0 +19366,0 +19367,0 +19368,0 +19369,0 +19370,0 +19371,0 +19372,0 +19373,0 +19374,0 +19375,0 +19376,0 +19377,0 +19378,0 +19379,0 +19380,0 +19381,0 +19382,0 +19383,0 +19384,0 +19385,0 +19386,0 +19387,0 +19388,0 +19389,0 +19390,0 +19391,0 +19392,0 +19393,0 +19394,0 +19395,0 +19396,0 +19397,0 +19398,0 +19399,0 +19400,0 +19401,0 +19402,0 +19403,0 +19404,0 +19405,0 +19406,0 +19407,0 +19408,0 +19409,0 +19410,0 +19411,0 +19412,0 +19413,0 +19414,0 +19415,0 +19416,0 +19417,0 +19418,0 +19419,0 +19420,0 +19421,0 +19422,0 +19423,0 +19424,0 +19425,0 +19426,0 +19427,0 +19428,0 +19429,0 +19430,0 +19431,0 +19432,0 +19433,0 +19434,0 +19435,0 +19436,0 +19437,0 +19438,0 +19439,0 +19440,0 +19441,0 +19442,0 +19443,0 +19444,0 +19445,0 +19446,0 +19447,0 +19448,0 +19449,0 +19450,0 +19451,0 +19452,0 +19453,0 +19454,0 +19455,0 +19456,0 +19457,0 +19458,0 +19459,0 +19460,0 +19461,0 +19462,0 +19463,0 +19464,0 +19465,0 +19466,0 +19467,0 +19468,0 +19469,0 +19470,0 +19471,0 +19472,0 +19473,0 +19474,0 +19475,0 +19476,0 +19477,0 +19478,0 +19479,0 +19480,0 +19481,0 +19482,0 +19483,0 +19484,0 +19485,0 +19486,0 +19487,0 +19488,0 +19489,0 +19490,0 +19491,0 +19492,0 +19493,0 +19494,0 +19495,0 +19496,0 +19497,0 +19498,0 +19499,0 +19500,0 +19501,0 +19502,0 +19503,0 +19504,0 +19505,0 +19506,0 +19507,0 +19508,0 +19509,0 +19510,0 +19511,0 +19512,0 +19513,0 +19514,0 +19515,0 +19516,0 +19517,0 +19518,0 +19519,0 +19520,0 +19521,0 +19522,0 +19523,0 +19524,0 +19525,0 +19526,0 +19527,0 +19528,0 +19529,0 +19530,0 +19531,0 +19532,0 +19533,0 +19534,0 +19535,0 +19536,0 +19537,0 +19538,0 +19539,0 +19540,0 +19541,0 +19542,0 +19543,0 +19544,0 +19545,0 +19546,0 +19547,0 +19548,0 +19549,0 +19550,0 +19551,0 +19552,0 +19553,0 +19554,0 +19555,0 +19556,0 +19557,0 +19558,0 +19559,0 +19560,0 +19561,0 +19562,0 +19563,0 +19564,0 +19565,0 +19566,0 +19567,0 +19568,0 +19569,0 +19570,0 +19571,0 +19572,0 +19573,0 +19574,0 +19575,0 +19576,0 +19577,0 +19578,0 +19579,0 +19580,0 +19581,0 +19582,0 +19583,0 +19584,0 +19585,0 +19586,0 +19587,0 +19588,0 +19589,0 +19590,0 +19591,0 +19592,0 +19593,0 +19594,0 +19595,0 +19596,0 +19597,0 +19598,0 +19599,0 +19600,0 +19601,0 +19602,0 +19603,0 +19604,0 +19605,0 +19606,0 +19607,0 +19608,0 +19609,0 +19610,0 +19611,0 +19612,0 +19613,0 +19614,0 +19615,0 +19616,0 +19617,0 +19618,0 +19619,0 +19620,0 +19621,0 +19622,0 +19623,0 +19624,0 +19625,0 +19626,0 +19627,0 +19628,0 +19629,0 +19630,0 +19631,0 +19632,0 +19633,0 +19634,0 +19635,0 +19636,0 +19637,0 +19638,0 +19639,0 +19640,0 +19641,0 +19642,0 +19643,0 +19644,0 +19645,0 +19646,0 +19647,0 +19648,0 +19649,0 +19650,0 +19651,0 +19652,0 +19653,0 +19654,0 +19655,0 +19656,0 +19657,0 +19658,0 +19659,0 +19660,0 +19661,0 +19662,0 +19663,0 +19664,0 +19665,0 +19666,0 +19667,0 +19668,0 +19669,0 +19670,0 +19671,0 +19672,0 +19673,0 +19674,0 +19675,0 +19676,0 +19677,0 +19678,0 +19679,0 +19680,0 +19681,0 +19682,0 +19683,0 +19684,0 +19685,0 +19686,0 +19687,0 +19688,0 +19689,0 +19690,0 +19691,0 +19692,0 +19693,0 +19694,0 +19695,0 +19696,0 +19697,0 +19698,0 +19699,0 +19700,0 +19701,0 +19702,0 +19703,0 +19704,0 +19705,0 +19706,0 +19707,0 +19708,0 +19709,0 +19710,0 +19711,0 +19712,0 +19713,0 +19714,0 +19715,0 +19716,0 +19717,0 +19718,0 +19719,0 +19720,0 +19721,0 +19722,0 +19723,0 +19724,0 +19725,0 +19726,0 +19727,0 +19728,0 +19729,0 +19730,0 +19731,0 +19732,0 +19733,0 +19734,0 +19735,0 +19736,0 +19737,0 +19738,0 +19739,0 +19740,0 +19741,0 +19742,0 +19743,0 +19744,0 +19745,0 +19746,0 +19747,0 +19748,0 +19749,0 +19750,0 +19751,0 +19752,0 +19753,0 +19754,0 +19755,0 +19756,0 +19757,0 +19758,0 +19759,0 +19760,0 +19761,0 +19762,0 +19763,0 +19764,0 +19765,0 +19766,0 +19767,0 +19768,0 +19769,0 +19770,0 +19771,0 +19772,0 +19773,0 +19774,0 +19775,0 +19776,0 +19777,0 +19778,0 +19779,0 +19780,0 +19781,0 +19782,0 +19783,0 +19784,0 +19785,0 +19786,0 +19787,0 +19788,0 +19789,0 +19790,0 +19791,0 +19792,0 +19793,0 +19794,0 +19795,0 +19796,0 +19797,0 +19798,0 +19799,0 +19800,0 +19801,0 +19802,0 +19803,0 +19804,0 +19805,0 +19806,0 +19807,0 +19808,0 +19809,0 +19810,0 +19811,0 +19812,0 +19813,0 +19814,0 +19815,0 +19816,0 +19817,0 +19818,0 +19819,0 +19820,0 +19821,0 +19822,0 +19823,0 +19824,0 +19825,0 +19826,0 +19827,0 +19828,0 +19829,0 +19830,0 +19831,0 +19832,0 +19833,0 +19834,0 +19835,0 +19836,0 +19837,0 +19838,0 +19839,0 +19840,0 +19841,0 +19842,0 +19843,0 +19844,0 +19845,0 +19846,0 +19847,0 +19848,0 +19849,0 +19850,0 +19851,0 +19852,0 +19853,0 +19854,0 +19855,0 +19856,0 +19857,0 +19858,0 +19859,0 +19860,0 +19861,0 +19862,0 +19863,0 +19864,0 +19865,0 +19866,0 +19867,0 +19868,0 +19869,0 +19870,0 +19871,0 +19872,0 +19873,0 +19874,0 +19875,0 +19876,0 +19877,0 +19878,0 +19879,0 +19880,0 +19881,0 +19882,0 +19883,0 +19884,0 +19885,0 +19886,0 +19887,0 +19888,0 +19889,0 +19890,0 +19891,0 +19892,0 +19893,0 +19894,0 +19895,0 +19896,0 +19897,0 +19898,0 +19899,0 +19900,0 +19901,0 +19902,0 +19903,0 +19904,0 +19905,0 +19906,0 +19907,0 +19908,0 +19909,0 +19910,0 +19911,0 +19912,0 +19913,0 +19914,0 +19915,0 +19916,0 +19917,0 +19918,0 +19919,0 +19920,0 +19921,0 +19922,0 +19923,0 +19924,0 +19925,0 +19926,0 +19927,0 +19928,0 +19929,0 +19930,0 +19931,0 +19932,0 +19933,0 +19934,0 +19935,0 +19936,0 +19937,0 +19938,0 +19939,0 +19940,0 +19941,0 +19942,0 +19943,0 +19944,0 +19945,0 +19946,0 +19947,0 +19948,0 +19949,0 +19950,0 +19951,0 +19952,0 +19953,0 +19954,0 +19955,0 +19956,0 +19957,0 +19958,0 +19959,0 +19960,0 +19961,0 +19962,0 +19963,0 +19964,0 +19965,0 +19966,0 +19967,0 +19968,0 +19969,0 +19970,0 +19971,0 +19972,0 +19973,0 +19974,0 +19975,0 +19976,0 +19977,0 +19978,0 +19979,0 +19980,0 +19981,0 +19982,0 +19983,0 +19984,0 +19985,0 +19986,0 +19987,0 +19988,0 +19989,0 +19990,0 +19991,0 +19992,0 +19993,0 +19994,0 +19995,0 +19996,0 +19997,0 +19998,0 +19999,0 +20000,0 +20001,0 +20002,0 +20003,0 +20004,0 +20005,0 +20006,0 +20007,0 +20008,0 +20009,0 +20010,0 +20011,0 +20012,0 +20013,0 +20014,0 +20015,0 +20016,0 +20017,0 +20018,0 +20019,0 +20020,0 +20021,0 +20022,0 +20023,0 +20024,0 +20025,0 +20026,0 +20027,0 +20028,0 +20029,0 +20030,0 +20031,0 +20032,0 +20033,0 +20034,0 +20035,0 +20036,0 +20037,0 +20038,0 +20039,0 +20040,0 +20041,0 +20042,0 +20043,0 +20044,0 +20045,0 +20046,0 +20047,0 +20048,0 +20049,0 +20050,0 +20051,0 +20052,0 +20053,0 +20054,0 +20055,0 +20056,0 +20057,0 +20058,0 +20059,0 +20060,0 +20061,0 +20062,0 +20063,0 +20064,0 +20065,0 +20066,0 +20067,0 +20068,0 +20069,0 +20070,0 +20071,0 +20072,0 +20073,0 +20074,0 +20075,0 +20076,0 +20077,0 +20078,0 +20079,0 +20080,0 +20081,0 +20082,0 +20083,0 +20084,0 +20085,0 +20086,0 +20087,0 +20088,0 +20089,0 +20090,0 +20091,0 +20092,0 +20093,0 +20094,0 +20095,0 +20096,0 +20097,0 +20098,0 +20099,0 +20100,0 +20101,0 +20102,0 +20103,0 +20104,0 +20105,0 +20106,0 +20107,0 +20108,0 +20109,0 +20110,0 +20111,0 +20112,0 +20113,0 +20114,0 +20115,0 +20116,0 +20117,0 +20118,0 +20119,0 +20120,0 +20121,0 +20122,0 +20123,0 +20124,0 +20125,0 +20126,0 +20127,0 +20128,0 +20129,0 +20130,0 +20131,0 +20132,0 +20133,0 +20134,0 +20135,0 +20136,0 +20137,0 +20138,0 +20139,0 +20140,0 +20141,0 +20142,0 +20143,0 +20144,0 +20145,0 +20146,0 +20147,0 +20148,0 +20149,0 +20150,0 +20151,0 +20152,0 +20153,0 +20154,0 +20155,0 +20156,0 +20157,0 +20158,0 +20159,0 +20160,0 +20161,0 +20162,0 +20163,0 +20164,0 +20165,0 +20166,0 +20167,0 +20168,0 +20169,0 +20170,0 +20171,0 +20172,0 +20173,0 +20174,0 +20175,0 +20176,0 +20177,0 +20178,0 +20179,0 +20180,0 +20181,0 +20182,0 +20183,0 +20184,0 +20185,0 +20186,0 +20187,0 +20188,0 +20189,0 +20190,0 +20191,0 +20192,0 +20193,0 +20194,0 +20195,0 +20196,0 +20197,0 +20198,0 +20199,0 +20200,0 +20201,0 +20202,0 +20203,0 +20204,0 +20205,0 +20206,0 +20207,0 +20208,0 +20209,0 +20210,0 +20211,0 +20212,0 +20213,0 +20214,0 +20215,0 +20216,0 +20217,0 +20218,0 +20219,0 +20220,0 +20221,0 +20222,0 +20223,0 +20224,0 +20225,0 +20226,0 +20227,0 +20228,0 +20229,0 +20230,0 +20231,0 +20232,0 +20233,0 +20234,0 +20235,0 +20236,0 +20237,0 +20238,0 +20239,0 +20240,0 +20241,0 +20242,0 +20243,0 +20244,0 +20245,0 +20246,0 +20247,0 +20248,0 +20249,0 +20250,0 +20251,0 +20252,0 +20253,0 +20254,0 +20255,0 +20256,0 +20257,0 +20258,0 +20259,0 +20260,0 +20261,0 +20262,0 +20263,0 +20264,0 +20265,0 +20266,0 +20267,0 +20268,0 +20269,0 +20270,0 +20271,0 +20272,0 +20273,0 +20274,0 +20275,0 +20276,0 +20277,0 +20278,0 +20279,0 +20280,0 +20281,0 +20282,0 +20283,0 +20284,0 +20285,0 +20286,0 +20287,0 +20288,0 +20289,0 +20290,0 +20291,0 +20292,0 +20293,0 +20294,0 +20295,0 +20296,0 +20297,0 +20298,0 +20299,0 +20300,0 +20301,0 +20302,0 +20303,0 +20304,0 +20305,0 +20306,0 +20307,0 +20308,0 +20309,0 +20310,0 +20311,0 +20312,0 +20313,0 +20314,0 +20315,0 +20316,0 +20317,0 +20318,0 +20319,0 +20320,0 +20321,0 +20322,0 +20323,0 +20324,0 +20325,0 +20326,0 +20327,0 +20328,0 +20329,0 +20330,0 +20331,0 +20332,0 +20333,0 +20334,0 +20335,0 +20336,0 +20337,0 +20338,0 +20339,0 +20340,0 +20341,0 +20342,0 +20343,0 +20344,0 +20345,0 +20346,0 +20347,0 +20348,0 +20349,0 +20350,0 +20351,0 +20352,0 +20353,0 +20354,0 +20355,0 +20356,0 +20357,0 +20358,0 +20359,0 +20360,0 +20361,0 +20362,0 +20363,0 +20364,0 +20365,0 +20366,0 +20367,0 +20368,0 +20369,0 +20370,0 +20371,0 +20372,0 +20373,0 +20374,0 +20375,0 +20376,0 +20377,0 +20378,0 +20379,0 +20380,0 +20381,0 +20382,0 +20383,0 +20384,0 +20385,0 +20386,0 +20387,0 +20388,0 +20389,0 +20390,0 +20391,0 +20392,0 +20393,0 +20394,0 +20395,0 +20396,0 +20397,0 +20398,0 +20399,0 +20400,0 +20401,0 +20402,0 +20403,0 +20404,0 +20405,0 +20406,0 +20407,0 +20408,0 +20409,0 +20410,0 +20411,0 +20412,0 +20413,0 +20414,0 +20415,0 +20416,0 +20417,0 +20418,0 +20419,0 +20420,0 +20421,0 +20422,0 +20423,0 +20424,0 +20425,0 +20426,0 +20427,0 +20428,0 +20429,0 +20430,0 +20431,0 +20432,0 +20433,0 +20434,0 +20435,0 +20436,0 +20437,0 +20438,0 +20439,0 +20440,0 +20441,0 +20442,0 +20443,0 +20444,0 +20445,0 +20446,0 +20447,0 +20448,0 +20449,0 +20450,0 +20451,0 +20452,0 +20453,0 +20454,0 +20455,0 +20456,0 +20457,0 +20458,0 +20459,0 +20460,0 +20461,0 +20462,0 +20463,0 +20464,0 +20465,0 +20466,0 +20467,0 +20468,0 +20469,0 +20470,0 +20471,0 +20472,0 +20473,0 +20474,0 +20475,0 +20476,0 +20477,0 +20478,0 +20479,0 +20480,0 +20481,0 +20482,0 +20483,0 +20484,0 +20485,0 +20486,0 +20487,0 +20488,0 +20489,0 +20490,0 +20491,0 +20492,0 +20493,0 +20494,0 +20495,0 +20496,0 +20497,0 +20498,0 +20499,0 +20500,0 +20501,0 +20502,0 +20503,0 +20504,0 +20505,0 +20506,0 +20507,0 +20508,0 +20509,0 +20510,0 +20511,0 +20512,0 +20513,0 +20514,0 +20515,0 +20516,0 +20517,0 +20518,0 +20519,0 +20520,0 +20521,0 +20522,0 +20523,0 +20524,0 +20525,0 +20526,0 +20527,0 +20528,0 +20529,0 +20530,0 +20531,0 +20532,0 +20533,0 +20534,0 +20535,0 +20536,0 +20537,0 +20538,0 +20539,0 +20540,0 +20541,0 +20542,0 +20543,0 +20544,0 +20545,0 +20546,0 +20547,0 +20548,0 +20549,0 +20550,0 +20551,0 +20552,0 +20553,0 +20554,0 +20555,0 +20556,0 +20557,0 +20558,0 +20559,0 +20560,0 +20561,0 +20562,0 +20563,0 +20564,0 +20565,0 +20566,0 +20567,0 +20568,0 +20569,0 +20570,0 +20571,0 +20572,0 +20573,0 +20574,0 +20575,0 +20576,0 +20577,0 +20578,0 +20579,0 +20580,0 +20581,0 +20582,0 +20583,0 +20584,0 +20585,0 +20586,0 +20587,0 +20588,0 +20589,0 +20590,0 +20591,0 +20592,0 +20593,0 +20594,0 +20595,0 +20596,0 +20597,0 +20598,0 +20599,0 +20600,0 +20601,0 +20602,0 +20603,0 +20604,0 +20605,0 +20606,0 +20607,0 +20608,0 +20609,0 +20610,0 +20611,0 +20612,0 +20613,0 +20614,0 +20615,0 +20616,0 +20617,0 +20618,0 +20619,0 +20620,0 +20621,0 +20622,0 +20623,0 +20624,0 +20625,0 +20626,0 +20627,0 +20628,0 +20629,0 +20630,0 +20631,0 +20632,0 +20633,0 +20634,0 +20635,0 +20636,0 +20637,0 +20638,0 +20639,0 +20640,0 +20641,0 +20642,0 +20643,0 +20644,0 +20645,0 +20646,0 +20647,0 +20648,0 +20649,0 +20650,0 +20651,0 +20652,0 +20653,0 +20654,0 +20655,0 +20656,0 +20657,0 +20658,0 +20659,0 +20660,0 +20661,0 +20662,0 +20663,0 +20664,0 +20665,0 +20666,0 +20667,0 +20668,0 +20669,0 +20670,0 +20671,0 +20672,0 +20673,0 +20674,0 +20675,0 +20676,0 +20677,0 +20678,0 +20679,0 +20680,0 +20681,0 +20682,0 +20683,0 +20684,0 +20685,0 +20686,0 +20687,0 +20688,0 +20689,0 +20690,0 +20691,0 +20692,0 +20693,0 +20694,0 +20695,0 +20696,0 +20697,0 +20698,0 +20699,0 +20700,0 +20701,0 +20702,0 +20703,0 +20704,0 +20705,0 +20706,0 +20707,0 +20708,0 +20709,0 +20710,0 +20711,0 +20712,0 +20713,0 +20714,0 +20715,0 +20716,0 +20717,0 +20718,0 +20719,0 +20720,0 +20721,0 +20722,0 +20723,0 +20724,0 +20725,0 +20726,0 +20727,0 +20728,0 +20729,0 +20730,0 +20731,0 +20732,0 +20733,0 +20734,0 +20735,0 +20736,0 +20737,0 +20738,0 +20739,0 +20740,0 +20741,0 +20742,0 +20743,0 +20744,0 +20745,0 +20746,0 +20747,0 +20748,0 +20749,0 +20750,0 +20751,0 +20752,0 +20753,0 +20754,0 +20755,0 +20756,0 +20757,0 +20758,0 +20759,0 +20760,0 +20761,0 +20762,0 +20763,0 +20764,0 +20765,0 +20766,0 +20767,0 +20768,0 +20769,0 +20770,0 +20771,0 +20772,0 +20773,0 +20774,0 +20775,0 +20776,0 +20777,0 +20778,0 +20779,0 +20780,0 +20781,0 +20782,0 +20783,0 +20784,0 +20785,0 +20786,0 +20787,0 +20788,0 +20789,0 +20790,0 +20791,0 +20792,0 +20793,0 +20794,0 +20795,0 +20796,0 +20797,0 +20798,0 +20799,0 +20800,0 +20801,0 +20802,0 +20803,0 +20804,0 +20805,0 +20806,0 +20807,0 +20808,0 +20809,0 +20810,0 +20811,0 +20812,0 +20813,0 +20814,0 +20815,0 +20816,0 +20817,0 +20818,0 +20819,0 +20820,0 +20821,0 +20822,0 +20823,0 +20824,0 +20825,0 +20826,0 +20827,0 +20828,0 +20829,0 +20830,0 +20831,0 +20832,0 +20833,0 +20834,0 +20835,0 +20836,0 +20837,0 +20838,0 +20839,0 +20840,0 +20841,0 +20842,0 +20843,0 +20844,0 +20845,0 +20846,0 +20847,0 +20848,0 +20849,0 +20850,0 +20851,0 +20852,0 +20853,0 +20854,0 +20855,0 +20856,0 +20857,0 +20858,0 +20859,0 +20860,0 +20861,0 +20862,0 +20863,0 +20864,0 +20865,0 +20866,0 +20867,0 +20868,0 +20869,0 +20870,0 +20871,0 +20872,0 +20873,0 +20874,0 +20875,0 +20876,0 +20877,0 +20878,0 +20879,0 +20880,0 +20881,0 +20882,0 +20883,0 +20884,0 +20885,0 +20886,0 +20887,0 +20888,0 +20889,0 +20890,0 +20891,0 +20892,0 +20893,0 +20894,0 +20895,0 +20896,0 +20897,0 +20898,0 +20899,0 +20900,0 +20901,0 +20902,0 +20903,0 +20904,0 +20905,0 +20906,0 +20907,0 +20908,0 +20909,0 +20910,0 +20911,0 +20912,0 +20913,0 +20914,0 +20915,0 +20916,0 +20917,0 +20918,0 +20919,0 +20920,0 +20921,0 +20922,0 +20923,0 +20924,0 +20925,0 +20926,0 +20927,0 +20928,0 +20929,0 +20930,0 +20931,0 +20932,0 +20933,0 +20934,0 +20935,0 +20936,0 +20937,0 +20938,0 +20939,0 +20940,0 +20941,0 +20942,0 +20943,0 +20944,0 +20945,0 +20946,0 +20947,0 +20948,0 +20949,0 +20950,0 +20951,0 +20952,0 +20953,0 +20954,0 +20955,0 +20956,0 +20957,0 +20958,0 +20959,0 +20960,0 +20961,0 +20962,0 +20963,0 +20964,0 +20965,0 +20966,0 +20967,0 +20968,0 +20969,0 +20970,0 +20971,0 +20972,0 +20973,0 +20974,0 +20975,0 +20976,0 +20977,0 +20978,0 +20979,0 +20980,0 +20981,0 +20982,0 +20983,0 +20984,0 +20985,0 +20986,0 +20987,0 +20988,0 +20989,0 +20990,0 +20991,0 +20992,0 +20993,0 +20994,0 +20995,0 +20996,0 +20997,0 +20998,0 +20999,0 +21000,0 +21001,0 +21002,0 +21003,0 +21004,0 +21005,0 +21006,0 +21007,0 +21008,0 +21009,0 +21010,0 +21011,0 +21012,0 +21013,0 +21014,0 +21015,0 +21016,0 +21017,0 +21018,0 +21019,0 +21020,0 +21021,0 +21022,0 +21023,0 +21024,0 +21025,0 +21026,0 +21027,0 +21028,0 +21029,0 +21030,0 +21031,0 +21032,0 +21033,0 +21034,0 +21035,0 +21036,0 +21037,0 +21038,0 +21039,0 +21040,0 +21041,0 +21042,0 +21043,0 +21044,0 +21045,0 +21046,0 +21047,0 +21048,0 +21049,0 +21050,0 +21051,0 +21052,0 +21053,0 +21054,0 +21055,0 +21056,0 +21057,0 +21058,0 +21059,0 +21060,0 +21061,0 +21062,0 +21063,0 +21064,0 +21065,0 +21066,0 +21067,0 +21068,0 +21069,0 +21070,0 +21071,0 +21072,0 +21073,0 +21074,0 +21075,0 +21076,0 +21077,0 +21078,0 +21079,0 +21080,0 +21081,0 +21082,0 +21083,0 +21084,0 +21085,0 +21086,0 +21087,0 +21088,0 +21089,0 +21090,0 +21091,0 +21092,0 +21093,0 +21094,0 +21095,0 +21096,0 +21097,0 +21098,0 +21099,0 +21100,0 +21101,0 +21102,0 +21103,0 +21104,0 +21105,0 +21106,0 +21107,0 +21108,0 +21109,0 +21110,0 +21111,0 +21112,0 +21113,0 +21114,0 +21115,0 +21116,0 +21117,0 +21118,0 +21119,0 +21120,0 +21121,0 +21122,0 +21123,0 +21124,0 +21125,0 +21126,0 +21127,0 +21128,0 +21129,0 +21130,0 +21131,0 +21132,0 +21133,0 +21134,0 +21135,0 +21136,0 +21137,0 +21138,0 +21139,0 +21140,0 +21141,0 +21142,0 +21143,0 +21144,0 +21145,0 +21146,0 +21147,0 +21148,0 +21149,0 +21150,0 +21151,0 +21152,0 +21153,0 +21154,0 +21155,0 +21156,0 +21157,0 +21158,0 +21159,0 +21160,0 +21161,0 +21162,0 +21163,0 +21164,0 +21165,0 +21166,0 +21167,0 +21168,0 +21169,0 +21170,0 +21171,0 +21172,0 +21173,0 +21174,0 +21175,0 +21176,0 +21177,0 +21178,0 +21179,0 +21180,0 +21181,0 +21182,0 +21183,0 +21184,0 +21185,0 +21186,0 +21187,0 +21188,0 +21189,0 +21190,0 +21191,0 +21192,0 +21193,0 +21194,0 +21195,0 +21196,0 +21197,0 +21198,0 +21199,0 +21200,0 +21201,0 +21202,0 +21203,0 +21204,0 +21205,0 +21206,0 +21207,0 +21208,0 +21209,0 +21210,0 +21211,0 +21212,0 +21213,0 +21214,0 +21215,0 +21216,0 +21217,0 +21218,0 +21219,0 +21220,0 +21221,0 +21222,0 +21223,0 +21224,0 +21225,0 +21226,0 +21227,0 +21228,0 +21229,0 +21230,0 +21231,0 +21232,0 +21233,0 +21234,0 +21235,0 +21236,0 +21237,0 +21238,0 +21239,0 +21240,0 +21241,0 +21242,0 +21243,0 +21244,0 +21245,0 +21246,0 +21247,0 +21248,0 +21249,0 +21250,0 +21251,0 +21252,0 +21253,0 +21254,0 +21255,0 +21256,0 +21257,0 +21258,0 +21259,0 +21260,0 +21261,0 +21262,0 +21263,0 +21264,0 +21265,0 +21266,0 +21267,0 +21268,0 +21269,0 +21270,0 +21271,0 +21272,0 +21273,0 +21274,0 +21275,0 +21276,0 +21277,0 +21278,0 +21279,0 +21280,0 +21281,0 +21282,0 +21283,0 +21284,0 +21285,0 +21286,0 +21287,0 +21288,0 +21289,0 +21290,0 +21291,0 +21292,0 +21293,0 +21294,0 +21295,0 +21296,0 +21297,0 +21298,0 +21299,0 +21300,0 +21301,0 +21302,0 +21303,0 +21304,0 +21305,0 +21306,0 +21307,0 +21308,0 +21309,0 +21310,0 +21311,0 +21312,0 +21313,0 +21314,0 +21315,0 +21316,0 +21317,0 +21318,0 +21319,0 +21320,0 +21321,0 +21322,0 +21323,0 +21324,0 +21325,0 +21326,0 +21327,0 +21328,0 +21329,0 +21330,0 +21331,0 +21332,0 +21333,0 +21334,0 +21335,0 +21336,0 +21337,0 +21338,0 +21339,0 +21340,0 +21341,0 +21342,0 +21343,0 +21344,0 +21345,0 +21346,0 +21347,0 +21348,0 +21349,0 +21350,0 +21351,0 +21352,0 +21353,0 +21354,0 +21355,0 +21356,0 +21357,0 +21358,0 +21359,0 +21360,0 +21361,0 +21362,0 +21363,0 +21364,0 +21365,0 +21366,0 +21367,0 +21368,0 +21369,0 +21370,0 +21371,0 +21372,0 +21373,0 +21374,0 +21375,0 +21376,0 +21377,0 +21378,0 +21379,0 +21380,0 +21381,0 +21382,0 +21383,0 +21384,0 +21385,0 +21386,0 +21387,0 +21388,0 +21389,0 +21390,0 +21391,0 +21392,0 +21393,0 +21394,0 +21395,0 +21396,0 +21397,0 +21398,0 +21399,0 +21400,0 +21401,0 +21402,0 +21403,0 +21404,0 +21405,0 +21406,0 +21407,0 +21408,0 +21409,0 +21410,0 +21411,0 +21412,0 +21413,0 +21414,0 +21415,0 +21416,0 +21417,0 +21418,0 +21419,0 +21420,0 +21421,0 +21422,0 +21423,0 +21424,0 +21425,0 +21426,0 +21427,0 +21428,0 +21429,0 +21430,0 +21431,0 +21432,0 +21433,0 +21434,0 +21435,0 +21436,0 +21437,0 +21438,0 +21439,0 +21440,0 +21441,0 +21442,0 +21443,0 +21444,0 +21445,0 +21446,0 +21447,0 +21448,0 +21449,0 +21450,0 +21451,0 +21452,0 +21453,0 +21454,0 +21455,0 +21456,0 +21457,0 +21458,0 +21459,0 +21460,0 +21461,0 +21462,0 +21463,0 +21464,0 +21465,0 +21466,0 +21467,0 +21468,0 +21469,0 +21470,0 +21471,0 +21472,0 +21473,0 +21474,0 +21475,0 +21476,0 +21477,0 +21478,0 +21479,0 +21480,0 +21481,0 +21482,0 +21483,0 +21484,0 +21485,0 +21486,0 +21487,0 +21488,0 +21489,0 +21490,0 +21491,0 +21492,0 +21493,0 +21494,0 +21495,0 +21496,0 +21497,0 +21498,0 +21499,0 +21500,0 +21501,0 +21502,0 +21503,0 +21504,0 +21505,0 +21506,0 +21507,0 +21508,0 +21509,0 +21510,0 +21511,0 +21512,0 +21513,0 +21514,0 +21515,0 +21516,0 +21517,0 +21518,0 +21519,0 +21520,0 +21521,0 +21522,0 +21523,0 +21524,0 +21525,0 +21526,0 +21527,0 +21528,0 +21529,0 +21530,0 +21531,0 +21532,0 +21533,0 +21534,0 +21535,0 +21536,0 +21537,0 +21538,0 +21539,0 +21540,0 +21541,0 +21542,0 +21543,0 +21544,0 +21545,0 +21546,0 +21547,0 +21548,0 +21549,0 +21550,0 +21551,0 +21552,0 +21553,0 +21554,0 +21555,0 +21556,0 +21557,0 +21558,0 +21559,0 +21560,0 +21561,0 +21562,0 +21563,0 +21564,0 +21565,0 +21566,0 +21567,0 +21568,0 +21569,0 +21570,0 +21571,0 +21572,0 +21573,0 +21574,0 +21575,0 +21576,0 +21577,0 +21578,0 +21579,0 +21580,0 +21581,0 +21582,0 +21583,0 +21584,0 +21585,0 +21586,0 +21587,0 +21588,0 +21589,0 +21590,0 +21591,0 +21592,0 +21593,0 +21594,0 +21595,0 +21596,0 +21597,0 +21598,0 +21599,0 +21600,0 +21601,0 +21602,0 +21603,0 +21604,0 +21605,0 +21606,0 +21607,0 +21608,0 +21609,0 +21610,0 +21611,0 +21612,0 +21613,0 +21614,0 +21615,0 +21616,0 +21617,0 +21618,0 +21619,0 +21620,0 +21621,0 +21622,0 +21623,0 +21624,0 +21625,0 +21626,0 +21627,0 +21628,0 +21629,0 +21630,0 +21631,0 +21632,0 +21633,0 +21634,0 +21635,0 +21636,0 +21637,0 +21638,0 +21639,0 +21640,0 +21641,0 +21642,0 +21643,0 +21644,0 +21645,0 +21646,0 +21647,0 +21648,0 +21649,0 +21650,0 +21651,0 +21652,0 +21653,0 +21654,0 +21655,0 +21656,0 +21657,0 +21658,0 +21659,0 +21660,0 +21661,0 +21662,0 +21663,0 +21664,0 +21665,0 +21666,0 +21667,0 +21668,0 +21669,0 +21670,0 +21671,0 +21672,0 +21673,0 +21674,0 +21675,0 +21676,0 +21677,0 +21678,0 +21679,0 +21680,0 +21681,0 +21682,0 +21683,0 +21684,0 +21685,0 +21686,0 +21687,0 +21688,0 +21689,0 +21690,0 +21691,0 +21692,0 +21693,0 +21694,0 +21695,0 +21696,0 +21697,0 +21698,0 +21699,0 +21700,0 +21701,0 +21702,0 +21703,0 +21704,0 +21705,0 +21706,0 +21707,0 +21708,0 +21709,0 +21710,0 +21711,0 +21712,0 +21713,0 +21714,0 +21715,0 +21716,0 +21717,0 +21718,0 +21719,0 +21720,0 +21721,0 +21722,0 +21723,0 +21724,0 +21725,0 +21726,0 +21727,0 +21728,0 +21729,0 +21730,0 +21731,0 +21732,0 +21733,0 +21734,0 +21735,0 +21736,0 +21737,0 +21738,0 +21739,0 +21740,0 +21741,0 +21742,0 +21743,0 +21744,0 +21745,0 +21746,0 +21747,0 +21748,0 +21749,0 +21750,0 +21751,0 +21752,0 +21753,0 +21754,0 +21755,0 +21756,0 +21757,0 +21758,0 +21759,0 +21760,0 +21761,0 +21762,0 +21763,0 +21764,0 +21765,0 +21766,0 +21767,0 +21768,0 +21769,0 +21770,0 +21771,0 +21772,0 +21773,0 +21774,0 +21775,0 +21776,0 +21777,0 +21778,0 +21779,0 +21780,0 +21781,0 +21782,0 +21783,0 +21784,0 +21785,0 +21786,0 +21787,0 +21788,0 +21789,0 +21790,0 +21791,0 +21792,0 +21793,0 +21794,0 +21795,0 +21796,0 +21797,0 +21798,0 +21799,0 +21800,0 +21801,0 +21802,0 +21803,0 +21804,0 +21805,0 +21806,0 +21807,0 +21808,0 +21809,0 +21810,0 +21811,0 +21812,0 +21813,0 +21814,0 +21815,0 +21816,0 +21817,0 +21818,0 +21819,0 +21820,0 +21821,0 +21822,0 +21823,0 +21824,0 +21825,0 +21826,0 +21827,0 +21828,0 +21829,0 +21830,0 +21831,0 +21832,0 +21833,0 +21834,0 +21835,0 +21836,0 +21837,0 +21838,0 +21839,0 +21840,0 +21841,0 +21842,0 +21843,0 +21844,0 +21845,0 +21846,0 +21847,0 +21848,0 +21849,0 +21850,0 +21851,0 +21852,0 +21853,0 +21854,0 +21855,0 +21856,0 +21857,0 +21858,0 +21859,0 +21860,0 +21861,0 +21862,0 +21863,0 +21864,0 +21865,0 +21866,0 +21867,0 +21868,0 +21869,0 +21870,0 +21871,0 +21872,0 +21873,0 +21874,0 +21875,0 +21876,0 +21877,0 +21878,0 +21879,0 +21880,0 +21881,0 +21882,0 +21883,0 +21884,0 +21885,0 +21886,0 +21887,0 +21888,0 +21889,0 +21890,0 +21891,0 +21892,0 +21893,0 +21894,0 +21895,0 +21896,0 +21897,0 +21898,0 +21899,0 +21900,0 +21901,0 +21902,0 +21903,0 +21904,0 +21905,0 +21906,0 +21907,0 +21908,0 +21909,0 +21910,0 +21911,0 +21912,0 +21913,0 +21914,0 +21915,0 +21916,0 +21917,0 +21918,0 +21919,0 +21920,0 +21921,0 +21922,0 +21923,0 +21924,0 +21925,0 +21926,0 +21927,0 +21928,0 +21929,0 +21930,0 +21931,0 +21932,0 +21933,0 +21934,0 +21935,0 +21936,0 +21937,0 +21938,0 +21939,0 +21940,0 +21941,0 +21942,0 +21943,0 +21944,0 +21945,0 +21946,0 +21947,0 +21948,0 +21949,0 +21950,0 +21951,0 +21952,0 +21953,0 +21954,0 +21955,0 +21956,0 +21957,0 +21958,0 +21959,0 +21960,0 +21961,0 +21962,0 +21963,0 +21964,0 +21965,0 +21966,0 +21967,0 +21968,0 +21969,0 +21970,0 +21971,0 +21972,0 +21973,0 +21974,0 +21975,0 +21976,0 +21977,0 +21978,0 +21979,0 +21980,0 +21981,0 +21982,0 +21983,0 +21984,0 +21985,0 +21986,0 +21987,0 +21988,0 +21989,0 +21990,0 +21991,0 +21992,0 +21993,0 +21994,0 +21995,0 +21996,0 +21997,0 +21998,0 +21999,0 +22000,0 +22001,0 +22002,0 +22003,0 +22004,0 +22005,0 +22006,0 +22007,0 +22008,0 +22009,0 +22010,0 +22011,0 +22012,0 +22013,0 +22014,0 +22015,0 +22016,0 +22017,0 +22018,0 +22019,0 +22020,0 +22021,0 +22022,0 +22023,0 +22024,0 +22025,0 +22026,0 +22027,0 +22028,0 +22029,0 +22030,0 +22031,0 +22032,0 +22033,0 +22034,0 +22035,0 +22036,0 +22037,0 +22038,0 +22039,0 +22040,0 +22041,0 +22042,0 +22043,0 +22044,0 +22045,0 +22046,0 +22047,0 +22048,0 +22049,0 +22050,0 +22051,0 +22052,0 +22053,0 +22054,0 +22055,0 +22056,0 +22057,0 +22058,0 +22059,0 +22060,0 +22061,0 +22062,0 +22063,0 +22064,0 +22065,0 +22066,0 +22067,0 +22068,0 +22069,0 +22070,0 +22071,0 +22072,0 +22073,0 +22074,0 +22075,0 +22076,0 +22077,0 +22078,0 +22079,0 +22080,0 +22081,0 +22082,0 +22083,0 +22084,0 +22085,0 +22086,0 +22087,0 +22088,0 +22089,0 +22090,0 +22091,0 +22092,0 +22093,0 +22094,0 +22095,0 +22096,0 +22097,0 +22098,0 +22099,0 +22100,0 +22101,0 +22102,0 +22103,0 +22104,0 +22105,0 +22106,0 +22107,0 +22108,0 +22109,0 +22110,0 +22111,0 +22112,0 +22113,0 +22114,0 +22115,0 +22116,0 +22117,0 +22118,0 +22119,0 +22120,0 +22121,0 +22122,0 +22123,0 +22124,0 +22125,0 +22126,0 +22127,0 +22128,0 +22129,0 +22130,0 +22131,0 +22132,0 +22133,0 +22134,0 +22135,0 +22136,0 +22137,0 +22138,0 +22139,0 +22140,0 +22141,0 +22142,0 +22143,0 +22144,0 +22145,0 +22146,0 +22147,0 +22148,0 +22149,0 +22150,0 +22151,0 +22152,0 +22153,0 +22154,0 +22155,0 +22156,0 +22157,0 +22158,0 +22159,0 +22160,0 +22161,0 +22162,0 +22163,0 +22164,0 +22165,0 +22166,0 +22167,0 +22168,0 +22169,0 +22170,0 +22171,0 +22172,0 +22173,0 +22174,0 +22175,0 +22176,0 +22177,0 +22178,0 +22179,0 +22180,0 +22181,0 +22182,0 +22183,0 +22184,0 +22185,0 +22186,0 +22187,0 +22188,0 +22189,0 +22190,0 +22191,0 +22192,0 +22193,0 +22194,0 +22195,0 +22196,0 +22197,0 +22198,0 +22199,0 +22200,0 +22201,0 +22202,0 +22203,0 +22204,0 +22205,0 +22206,0 +22207,0 +22208,0 +22209,0 +22210,0 +22211,0 +22212,0 +22213,0 +22214,0 +22215,0 +22216,0 +22217,0 +22218,0 +22219,0 +22220,0 +22221,0 +22222,0 +22223,0 +22224,0 +22225,0 +22226,0 +22227,0 +22228,0 +22229,0 +22230,0 +22231,0 +22232,0 +22233,0 +22234,0 +22235,0 +22236,0 +22237,0 +22238,0 +22239,0 +22240,0 +22241,0 +22242,0 +22243,0 +22244,0 +22245,0 +22246,0 +22247,0 +22248,0 +22249,0 +22250,0 +22251,0 +22252,0 +22253,0 +22254,0 +22255,0 +22256,0 +22257,0 +22258,0 +22259,0 +22260,0 +22261,0 +22262,0 +22263,0 +22264,0 +22265,0 +22266,0 +22267,0 +22268,0 +22269,0 +22270,0 +22271,0 +22272,0 +22273,0 +22274,0 +22275,0 +22276,0 +22277,0 +22278,0 +22279,0 +22280,0 +22281,0 +22282,0 +22283,0 +22284,0 +22285,0 +22286,0 +22287,0 +22288,0 +22289,0 +22290,0 +22291,0 +22292,0 +22293,0 +22294,0 +22295,0 +22296,0 +22297,0 +22298,0 +22299,0 +22300,0 +22301,0 +22302,0 +22303,0 +22304,0 +22305,0 +22306,0 +22307,0 +22308,0 +22309,0 +22310,0 +22311,0 +22312,0 +22313,0 +22314,0 +22315,0 +22316,0 +22317,0 +22318,0 +22319,0 +22320,0 +22321,0 +22322,0 +22323,0 +22324,0 +22325,0 +22326,0 +22327,0 +22328,0 +22329,0 +22330,0 +22331,0 +22332,0 +22333,0 +22334,0 +22335,0 +22336,0 +22337,0 +22338,0 +22339,0 +22340,0 +22341,0 +22342,0 +22343,0 +22344,0 +22345,0 +22346,0 +22347,0 +22348,0 +22349,0 +22350,0 +22351,0 +22352,0 +22353,0 +22354,0 +22355,0 +22356,0 +22357,0 +22358,0 +22359,0 +22360,0 +22361,0 +22362,0 +22363,0 +22364,0 +22365,0 +22366,0 +22367,0 +22368,0 +22369,0 +22370,0 +22371,0 +22372,0 +22373,0 +22374,0 +22375,0 +22376,0 +22377,0 +22378,0 +22379,0 +22380,0 +22381,0 +22382,0 +22383,0 +22384,0 +22385,0 +22386,0 +22387,0 +22388,0 +22389,0 +22390,0 +22391,0 +22392,0 +22393,0 +22394,0 +22395,0 +22396,0 +22397,0 +22398,0 +22399,0 +22400,0 +22401,0 +22402,0 +22403,0 +22404,0 +22405,0 +22406,0 +22407,0 +22408,0 +22409,0 +22410,0 +22411,0 +22412,0 +22413,0 +22414,0 +22415,0 +22416,0 +22417,0 +22418,0 +22419,0 +22420,0 +22421,0 +22422,0 +22423,0 +22424,0 +22425,0 +22426,0 +22427,0 +22428,0 +22429,0 +22430,0 +22431,0 +22432,0 +22433,0 +22434,0 +22435,0 +22436,0 +22437,0 +22438,0 +22439,0 +22440,0 +22441,0 +22442,0 +22443,0 +22444,0 +22445,0 +22446,0 +22447,0 +22448,0 +22449,0 +22450,0 +22451,0 +22452,0 +22453,0 +22454,0 +22455,0 +22456,0 +22457,0 +22458,0 +22459,0 +22460,0 +22461,0 +22462,0 +22463,0 +22464,0 +22465,0 +22466,0 +22467,0 +22468,0 +22469,0 +22470,0 +22471,0 +22472,0 +22473,0 +22474,0 +22475,0 +22476,0 +22477,0 +22478,0 +22479,0 +22480,0 +22481,0 +22482,0 +22483,0 +22484,0 +22485,0 +22486,0 +22487,0 +22488,0 +22489,0 +22490,0 +22491,0 +22492,0 +22493,0 +22494,0 +22495,0 +22496,0 +22497,0 +22498,0 +22499,0 +22500,0 +22501,0 +22502,0 +22503,0 +22504,0 +22505,0 +22506,0 +22507,0 +22508,0 +22509,0 +22510,0 +22511,0 +22512,0 +22513,0 +22514,0 +22515,0 +22516,0 +22517,0 +22518,0 +22519,0 +22520,0 +22521,0 +22522,0 +22523,0 +22524,0 +22525,0 +22526,0 +22527,0 +22528,0 +22529,0 +22530,0 +22531,0 +22532,0 +22533,0 +22534,0 +22535,0 +22536,0 +22537,0 +22538,0 +22539,0 +22540,0 +22541,0 +22542,0 +22543,0 +22544,0 +22545,0 +22546,0 +22547,0 +22548,0 +22549,0 +22550,0 +22551,0 +22552,0 +22553,0 +22554,0 +22555,0 +22556,0 +22557,0 +22558,0 +22559,0 +22560,0 +22561,0 +22562,0 +22563,0 +22564,0 +22565,0 +22566,0 +22567,0 +22568,0 +22569,0 +22570,0 +22571,0 +22572,0 +22573,0 +22574,0 +22575,0 +22576,0 +22577,0 +22578,0 +22579,0 +22580,0 +22581,0 +22582,0 +22583,0 +22584,0 +22585,0 +22586,0 +22587,0 +22588,0 +22589,0 +22590,0 +22591,0 +22592,0 +22593,0 +22594,0 +22595,0 +22596,0 +22597,0 +22598,0 +22599,0 +22600,0 +22601,0 +22602,0 +22603,0 +22604,0 +22605,0 +22606,0 +22607,0 +22608,0 +22609,0 +22610,0 +22611,0 +22612,0 +22613,0 +22614,0 +22615,0 +22616,0 +22617,0 +22618,0 +22619,0 +22620,0 +22621,0 +22622,0 +22623,0 +22624,0 +22625,0 +22626,0 +22627,0 +22628,0 +22629,0 +22630,0 +22631,0 +22632,0 +22633,0 +22634,0 +22635,0 +22636,0 +22637,0 +22638,0 +22639,0 +22640,0 +22641,0 +22642,0 +22643,0 +22644,0 +22645,0 +22646,0 +22647,0 +22648,0 +22649,0 +22650,0 +22651,0 +22652,0 +22653,0 +22654,0 +22655,0 +22656,0 +22657,0 +22658,0 +22659,0 +22660,0 +22661,0 +22662,0 +22663,0 +22664,0 +22665,0 +22666,0 +22667,0 +22668,0 +22669,0 +22670,0 +22671,0 +22672,0 +22673,0 +22674,0 +22675,0 +22676,0 +22677,0 +22678,0 +22679,0 +22680,0 +22681,0 +22682,0 +22683,0 +22684,0 +22685,0 +22686,0 +22687,0 +22688,0 +22689,0 +22690,0 +22691,0 +22692,0 +22693,0 +22694,0 +22695,0 +22696,0 +22697,0 +22698,0 +22699,0 +22700,0 +22701,0 +22702,0 +22703,0 +22704,0 +22705,0 +22706,0 +22707,0 +22708,0 +22709,0 +22710,0 +22711,0 +22712,0 +22713,0 +22714,0 +22715,0 +22716,0 +22717,0 +22718,0 +22719,0 +22720,0 +22721,0 +22722,0 +22723,0 +22724,0 +22725,0 +22726,0 +22727,0 +22728,0 +22729,0 +22730,0 +22731,0 +22732,0 +22733,0 +22734,0 +22735,0 +22736,0 +22737,0 +22738,0 +22739,0 +22740,0 +22741,0 +22742,0 +22743,0 +22744,0 +22745,0 +22746,0 +22747,0 +22748,0 +22749,0 +22750,0 +22751,0 +22752,0 +22753,0 +22754,0 +22755,0 +22756,0 +22757,0 +22758,0 +22759,0 +22760,0 +22761,0 +22762,0 +22763,0 +22764,0 +22765,0 +22766,0 +22767,0 +22768,0 +22769,0 +22770,0 +22771,0 +22772,0 +22773,0 +22774,0 +22775,0 +22776,0 +22777,0 +22778,0 +22779,0 +22780,0 +22781,0 +22782,0 +22783,0 +22784,0 +22785,0 +22786,0 +22787,0 +22788,0 +22789,0 +22790,0 +22791,0 +22792,0 +22793,0 +22794,0 +22795,0 +22796,0 +22797,0 +22798,0 +22799,0 +22800,0 +22801,0 +22802,0 +22803,0 +22804,0 +22805,0 +22806,0 +22807,0 +22808,0 +22809,0 +22810,0 +22811,0 +22812,0 +22813,0 +22814,0 +22815,0 +22816,0 +22817,0 +22818,0 +22819,0 +22820,0 +22821,0 +22822,0 +22823,0 +22824,0 +22825,0 +22826,0 +22827,0 +22828,0 +22829,0 +22830,0 +22831,0 +22832,0 +22833,0 +22834,0 +22835,0 +22836,0 +22837,0 +22838,0 +22839,0 +22840,0 +22841,0 +22842,0 +22843,0 +22844,0 +22845,0 +22846,0 +22847,0 +22848,0 +22849,0 +22850,0 +22851,0 +22852,0 +22853,0 +22854,0 +22855,0 +22856,0 +22857,0 +22858,0 +22859,0 +22860,0 +22861,0 +22862,0 +22863,0 +22864,0 +22865,0 +22866,0 +22867,0 +22868,0 +22869,0 +22870,0 +22871,0 +22872,0 +22873,0 +22874,0 +22875,0 +22876,0 +22877,0 +22878,0 +22879,0 +22880,0 +22881,0 +22882,0 +22883,0 +22884,0 +22885,0 +22886,0 +22887,0 +22888,0 +22889,0 +22890,0 +22891,0 +22892,0 +22893,0 +22894,0 +22895,0 +22896,0 +22897,0 +22898,0 +22899,0 +22900,0 +22901,0 +22902,0 +22903,0 +22904,0 +22905,0 +22906,0 +22907,0 +22908,0 +22909,0 +22910,0 +22911,0 +22912,0 +22913,0 +22914,0 +22915,0 +22916,0 +22917,0 +22918,0 +22919,0 +22920,0 +22921,0 +22922,0 +22923,0 +22924,0 +22925,0 +22926,0 +22927,0 +22928,0 +22929,0 +22930,0 +22931,0 +22932,0 +22933,0 +22934,0 +22935,0 +22936,0 +22937,0 +22938,0 +22939,0 +22940,0 +22941,0 +22942,0 +22943,0 +22944,0 +22945,0 +22946,0 +22947,0 +22948,0 +22949,0 +22950,0 +22951,0 +22952,0 +22953,0 +22954,0 +22955,0 +22956,0 +22957,0 +22958,0 +22959,0 +22960,0 +22961,0 +22962,0 +22963,0 +22964,0 +22965,0 +22966,0 +22967,0 +22968,0 +22969,0 +22970,0 +22971,0 +22972,0 +22973,0 +22974,0 +22975,0 +22976,0 +22977,0 +22978,0 +22979,0 +22980,0 +22981,0 +22982,0 +22983,0 +22984,0 +22985,0 +22986,0 +22987,0 +22988,0 +22989,0 +22990,0 +22991,0 +22992,0 +22993,0 +22994,0 +22995,0 +22996,0 +22997,0 +22998,0 +22999,0 +23000,0 +23001,0 +23002,0 +23003,0 +23004,0 +23005,0 +23006,0 +23007,0 +23008,0 +23009,0 +23010,0 +23011,0 +23012,0 +23013,0 +23014,0 +23015,0 +23016,0 +23017,0 +23018,0 +23019,0 +23020,0 +23021,0 +23022,0 +23023,0 +23024,0 +23025,0 +23026,0 +23027,0 +23028,0 +23029,0 +23030,0 +23031,0 +23032,0 +23033,0 +23034,0 +23035,0 +23036,0 +23037,0 +23038,0 +23039,0 +23040,0 +23041,0 +23042,0 +23043,0 +23044,0 +23045,0 +23046,0 +23047,0 +23048,0 +23049,0 +23050,0 +23051,0 +23052,0 +23053,0 +23054,0 +23055,0 +23056,0 +23057,0 +23058,0 +23059,0 +23060,0 +23061,0 +23062,0 +23063,0 +23064,0 +23065,0 +23066,0 +23067,0 +23068,0 +23069,0 +23070,0 +23071,0 +23072,0 +23073,0 +23074,0 +23075,0 +23076,0 +23077,0 +23078,0 +23079,0 +23080,0 +23081,0 +23082,0 +23083,0 +23084,0 +23085,0 +23086,0 +23087,0 +23088,0 +23089,0 +23090,0 +23091,0 +23092,0 +23093,0 +23094,0 +23095,0 +23096,0 +23097,0 +23098,0 +23099,0 +23100,0 +23101,0 +23102,0 +23103,0 +23104,0 +23105,0 +23106,0 +23107,0 +23108,0 +23109,0 +23110,0 +23111,0 +23112,0 +23113,0 +23114,0 +23115,0 +23116,0 +23117,0 +23118,0 +23119,0 +23120,0 +23121,0 +23122,0 +23123,0 +23124,0 +23125,0 +23126,0 +23127,0 +23128,0 +23129,0 +23130,0 +23131,0 +23132,0 +23133,0 +23134,0 +23135,0 +23136,0 +23137,0 +23138,0 +23139,0 +23140,0 +23141,0 +23142,0 +23143,0 +23144,0 +23145,0 +23146,0 +23147,0 +23148,0 +23149,0 +23150,0 +23151,0 +23152,0 +23153,0 +23154,0 +23155,0 +23156,0 +23157,0 +23158,0 +23159,0 +23160,0 +23161,0 +23162,0 +23163,0 +23164,0 +23165,0 +23166,0 +23167,0 +23168,0 +23169,0 +23170,0 +23171,0 +23172,0 +23173,0 +23174,0 +23175,0 +23176,0 +23177,0 +23178,0 +23179,0 +23180,0 +23181,0 +23182,0 +23183,0 +23184,0 +23185,0 +23186,0 +23187,0 +23188,0 +23189,0 +23190,0 +23191,0 +23192,0 +23193,0 +23194,0 +23195,0 +23196,0 +23197,0 +23198,0 +23199,0 +23200,0 +23201,0 +23202,0 +23203,0 +23204,0 +23205,0 +23206,0 +23207,0 +23208,0 +23209,0 +23210,0 +23211,0 +23212,0 +23213,0 +23214,0 +23215,0 +23216,0 +23217,0 +23218,0 +23219,0 +23220,0 +23221,0 +23222,0 +23223,0 +23224,0 +23225,0 +23226,0 +23227,0 +23228,0 +23229,0 +23230,0 +23231,0 +23232,0 +23233,0 +23234,0 +23235,0 +23236,0 +23237,0 +23238,0 +23239,0 +23240,0 +23241,0 +23242,0 +23243,0 +23244,0 +23245,0 +23246,0 +23247,0 +23248,0 +23249,0 +23250,0 +23251,0 +23252,0 +23253,0 +23254,0 +23255,0 +23256,0 +23257,0 +23258,0 +23259,0 +23260,0 +23261,0 +23262,0 +23263,0 +23264,0 +23265,0 +23266,0 +23267,0 +23268,0 +23269,0 +23270,0 +23271,0 +23272,0 +23273,0 +23274,0 +23275,0 +23276,0 +23277,0 +23278,0 +23279,0 +23280,0 +23281,0 +23282,0 +23283,0 +23284,0 +23285,0 +23286,0 +23287,0 +23288,0 +23289,0 +23290,0 +23291,0 +23292,0 +23293,0 +23294,0 +23295,0 +23296,0 +23297,0 +23298,0 +23299,0 +23300,0 +23301,0 +23302,0 +23303,0 +23304,0 +23305,0 +23306,0 +23307,0 +23308,0 +23309,0 +23310,0 +23311,0 +23312,0 +23313,0 +23314,0 +23315,0 +23316,0 +23317,0 +23318,0 +23319,0 +23320,0 +23321,0 +23322,0 +23323,0 +23324,0 +23325,0 +23326,0 +23327,0 +23328,0 +23329,0 +23330,0 +23331,0 +23332,0 +23333,0 +23334,0 +23335,0 +23336,0 +23337,0 +23338,0 +23339,0 +23340,0 +23341,0 +23342,0 +23343,0 +23344,0 +23345,0 +23346,0 +23347,0 +23348,0 +23349,0 +23350,0 +23351,0 +23352,0 +23353,0 +23354,0 +23355,0 +23356,0 +23357,0 +23358,0 +23359,0 +23360,0 +23361,0 +23362,0 +23363,0 +23364,0 +23365,0 +23366,0 +23367,0 +23368,0 +23369,0 +23370,0 +23371,0 +23372,0 +23373,0 +23374,0 +23375,0 +23376,0 +23377,0 +23378,0 +23379,0 +23380,0 +23381,0 +23382,0 +23383,0 +23384,0 +23385,0 +23386,0 +23387,0 +23388,0 +23389,0 +23390,0 +23391,0 +23392,0 +23393,0 +23394,0 +23395,0 +23396,0 +23397,0 +23398,0 +23399,0 +23400,0 +23401,0 +23402,0 +23403,0 +23404,0 +23405,0 +23406,0 +23407,0 +23408,0 +23409,0 +23410,0 +23411,0 +23412,0 +23413,0 +23414,0 +23415,0 +23416,0 +23417,0 +23418,0 +23419,0 +23420,0 +23421,0 +23422,0 +23423,0 +23424,0 +23425,0 +23426,0 +23427,0 +23428,0 +23429,0 +23430,0 +23431,0 +23432,0 +23433,0 +23434,0 +23435,0 +23436,0 +23437,0 +23438,0 +23439,0 +23440,0 +23441,0 +23442,0 +23443,0 +23444,0 +23445,0 +23446,0 +23447,0 +23448,0 +23449,0 +23450,0 +23451,0 +23452,0 +23453,0 +23454,0 +23455,0 +23456,0 +23457,0 +23458,0 +23459,0 +23460,0 +23461,0 +23462,0 +23463,0 +23464,0 +23465,0 +23466,0 +23467,0 +23468,0 +23469,0 +23470,0 +23471,0 +23472,0 +23473,0 +23474,0 +23475,0 +23476,0 +23477,0 +23478,0 +23479,0 +23480,0 +23481,0 +23482,0 +23483,0 +23484,0 +23485,0 +23486,0 +23487,0 +23488,0 +23489,0 +23490,0 +23491,0 +23492,0 +23493,0 +23494,0 +23495,0 +23496,0 +23497,0 +23498,0 +23499,0 +23500,0 +23501,0 +23502,0 +23503,0 +23504,0 +23505,0 +23506,0 +23507,0 +23508,0 +23509,0 +23510,0 +23511,0 +23512,0 +23513,0 +23514,0 +23515,0 +23516,0 +23517,0 +23518,0 +23519,0 +23520,0 +23521,0 +23522,0 +23523,0 +23524,0 +23525,0 +23526,0 +23527,0 +23528,0 +23529,0 +23530,0 +23531,0 +23532,0 +23533,0 +23534,0 +23535,0 +23536,0 +23537,0 +23538,0 +23539,0 +23540,0 +23541,0 +23542,0 +23543,0 +23544,0 +23545,0 +23546,0 +23547,0 +23548,0 +23549,0 +23550,0 +23551,0 +23552,0 +23553,0 +23554,0 +23555,0 +23556,0 +23557,0 +23558,0 +23559,0 +23560,0 +23561,0 +23562,0 +23563,0 +23564,0 +23565,0 +23566,0 +23567,0 +23568,0 +23569,0 +23570,0 +23571,0 +23572,0 +23573,0 +23574,0 +23575,0 +23576,0 +23577,0 +23578,0 +23579,0 +23580,0 +23581,0 +23582,0 +23583,0 +23584,0 +23585,0 +23586,0 +23587,0 +23588,0 +23589,0 +23590,0 +23591,0 +23592,0 +23593,0 +23594,0 +23595,0 +23596,0 +23597,0 +23598,0 +23599,0 +23600,0 +23601,0 +23602,0 +23603,0 +23604,0 +23605,0 +23606,0 +23607,0 +23608,0 +23609,0 +23610,0 +23611,0 +23612,0 +23613,0 +23614,0 +23615,0 +23616,0 +23617,0 +23618,0 +23619,0 +23620,0 +23621,0 +23622,0 +23623,0 +23624,0 +23625,0 +23626,0 +23627,0 +23628,0 +23629,0 +23630,0 +23631,0 +23632,0 +23633,0 +23634,0 +23635,0 +23636,0 +23637,0 +23638,0 +23639,0 +23640,0 +23641,0 +23642,0 +23643,0 +23644,0 +23645,0 +23646,0 +23647,0 +23648,0 +23649,0 +23650,0 +23651,0 +23652,0 +23653,0 +23654,0 +23655,0 +23656,0 +23657,0 +23658,0 +23659,0 +23660,0 +23661,0 +23662,0 +23663,0 +23664,0 +23665,0 +23666,0 +23667,0 +23668,0 +23669,0 +23670,0 +23671,0 +23672,0 +23673,0 +23674,0 +23675,0 +23676,0 +23677,0 +23678,0 +23679,0 +23680,0 +23681,0 +23682,0 +23683,0 +23684,0 +23685,0 +23686,0 +23687,0 +23688,0 +23689,0 +23690,0 +23691,0 +23692,0 +23693,0 +23694,0 +23695,0 +23696,0 +23697,0 +23698,0 +23699,0 +23700,0 +23701,0 +23702,0 +23703,0 +23704,0 +23705,0 +23706,0 +23707,0 +23708,0 +23709,0 +23710,0 +23711,0 +23712,0 +23713,0 +23714,0 +23715,0 +23716,0 +23717,0 +23718,0 +23719,0 +23720,0 +23721,0 +23722,0 +23723,0 +23724,0 +23725,0 +23726,0 +23727,0 +23728,0 +23729,0 +23730,0 +23731,0 +23732,0 +23733,0 +23734,0 +23735,0 +23736,0 +23737,0 +23738,0 +23739,0 +23740,0 +23741,0 +23742,0 +23743,0 +23744,0 +23745,0 +23746,0 +23747,0 +23748,0 +23749,0 +23750,0 +23751,0 +23752,0 +23753,0 +23754,0 +23755,0 +23756,0 +23757,0 +23758,0 +23759,0 +23760,0 +23761,0 +23762,0 +23763,0 +23764,0 +23765,0 +23766,0 +23767,0 +23768,0 +23769,0 +23770,0 +23771,0 +23772,0 +23773,0 +23774,0 +23775,0 +23776,0 +23777,0 +23778,0 +23779,0 +23780,0 +23781,0 +23782,0 +23783,0 +23784,0 +23785,0 +23786,0 +23787,0 +23788,0 +23789,0 +23790,0 +23791,0 +23792,0 +23793,0 +23794,0 +23795,0 +23796,0 +23797,0 +23798,0 +23799,0 +23800,0 +23801,0 +23802,0 +23803,0 +23804,0 +23805,0 +23806,0 +23807,0 +23808,0 +23809,0 +23810,0 +23811,0 +23812,0 +23813,0 +23814,0 +23815,0 +23816,0 +23817,0 +23818,0 +23819,0 +23820,0 +23821,0 +23822,0 +23823,0 +23824,0 +23825,0 +23826,0 +23827,0 +23828,0 +23829,0 +23830,0 +23831,0 +23832,0 +23833,0 +23834,0 +23835,0 +23836,0 +23837,0 +23838,0 +23839,0 +23840,0 +23841,0 +23842,0 +23843,0 +23844,0 +23845,0 +23846,0 +23847,0 +23848,0 +23849,0 +23850,0 +23851,0 +23852,0 +23853,0 +23854,0 +23855,0 +23856,0 +23857,0 +23858,0 +23859,0 +23860,0 +23861,0 +23862,0 +23863,0 +23864,0 +23865,0 +23866,0 +23867,0 +23868,0 +23869,0 +23870,0 +23871,0 +23872,0 +23873,0 +23874,0 +23875,0 +23876,0 +23877,0 +23878,0 +23879,0 +23880,0 +23881,0 +23882,0 +23883,0 +23884,0 +23885,0 +23886,0 +23887,0 +23888,0 +23889,0 +23890,0 +23891,0 +23892,0 +23893,0 +23894,0 +23895,0 +23896,0 +23897,0 +23898,0 +23899,0 +23900,0 +23901,0 +23902,0 +23903,0 +23904,0 +23905,0 +23906,0 +23907,0 +23908,0 +23909,0 +23910,0 +23911,0 +23912,0 +23913,0 +23914,0 +23915,0 +23916,0 +23917,0 +23918,0 +23919,0 +23920,0 +23921,0 +23922,0 +23923,0 +23924,0 +23925,0 +23926,0 +23927,0 +23928,0 +23929,0 +23930,0 +23931,0 +23932,0 +23933,0 +23934,0 +23935,0 +23936,0 +23937,0 +23938,0 +23939,0 +23940,0 +23941,0 +23942,0 +23943,0 +23944,0 +23945,0 +23946,0 +23947,0 +23948,0 +23949,0 +23950,0 +23951,0 +23952,0 +23953,0 +23954,0 +23955,0 +23956,0 +23957,0 +23958,0 +23959,0 +23960,0 +23961,0 +23962,0 +23963,0 +23964,0 +23965,0 +23966,0 +23967,0 +23968,0 +23969,0 +23970,0 +23971,0 +23972,0 +23973,0 +23974,0 +23975,0 +23976,0 +23977,0 +23978,0 +23979,0 +23980,0 +23981,0 +23982,0 +23983,0 +23984,0 +23985,0 +23986,0 +23987,0 +23988,0 +23989,0 +23990,0 +23991,0 +23992,0 +23993,0 +23994,0 +23995,0 +23996,0 +23997,0 +23998,0 +23999,0 +24000,0 +24001,0 +24002,0 +24003,0 +24004,0 +24005,0 +24006,0 +24007,0 +24008,0 +24009,0 +24010,0 +24011,0 +24012,0 +24013,0 +24014,0 +24015,0 +24016,0 +24017,0 +24018,0 +24019,0 +24020,0 +24021,0 +24022,0 +24023,0 +24024,0 +24025,0 +24026,0 +24027,0 +24028,0 +24029,0 +24030,0 +24031,0 +24032,0 +24033,0 +24034,0 +24035,0 +24036,0 +24037,0 +24038,0 +24039,0 +24040,0 +24041,0 +24042,0 +24043,0 +24044,0 +24045,0 +24046,0 +24047,0 +24048,0 +24049,0 +24050,0 +24051,0 +24052,0 +24053,0 +24054,0 +24055,0 +24056,0 +24057,0 +24058,0 +24059,0 +24060,0 +24061,0 +24062,0 +24063,0 +24064,0 +24065,0 +24066,0 +24067,0 +24068,0 +24069,0 +24070,0 +24071,0 +24072,0 +24073,0 +24074,0 +24075,0 +24076,0 +24077,0 +24078,0 +24079,0 +24080,0 +24081,0 +24082,0 +24083,0 +24084,0 +24085,0 +24086,0 +24087,0 +24088,0 +24089,0 +24090,0 +24091,0 +24092,0 +24093,0 +24094,0 +24095,0 +24096,0 +24097,0 +24098,0 +24099,0 +24100,0 +24101,0 +24102,0 +24103,0 +24104,0 +24105,0 +24106,0 +24107,0 +24108,0 +24109,0 +24110,0 +24111,0 +24112,0 +24113,0 +24114,0 +24115,0 +24116,0 +24117,0 +24118,0 +24119,0 +24120,0 +24121,0 +24122,0 +24123,0 +24124,0 +24125,0 +24126,0 +24127,0 +24128,0 +24129,0 +24130,0 +24131,0 +24132,0 +24133,0 +24134,0 +24135,0 +24136,0 +24137,0 +24138,0 +24139,0 +24140,0 +24141,0 +24142,0 +24143,0 +24144,0 +24145,0 +24146,0 +24147,0 +24148,0 +24149,0 +24150,0 +24151,0 +24152,0 +24153,0 +24154,0 +24155,0 +24156,0 +24157,0 +24158,0 +24159,0 +24160,0 +24161,0 +24162,0 +24163,0 +24164,0 +24165,0 +24166,0 +24167,0 +24168,0 +24169,0 +24170,0 +24171,0 +24172,0 +24173,0 +24174,0 +24175,0 +24176,0 +24177,0 +24178,0 +24179,0 +24180,0 +24181,0 +24182,0 +24183,0 +24184,0 +24185,0 +24186,0 +24187,0 +24188,0 +24189,0 +24190,0 +24191,0 +24192,0 +24193,0 +24194,0 +24195,0 +24196,0 +24197,0 +24198,0 +24199,0 +24200,0 +24201,0 +24202,0 +24203,0 +24204,0 +24205,0 +24206,0 +24207,0 +24208,0 +24209,0 +24210,0 +24211,0 +24212,0 +24213,0 +24214,0 +24215,0 +24216,0 +24217,0 +24218,0 +24219,0 +24220,0 +24221,0 +24222,0 +24223,0 +24224,0 +24225,0 +24226,0 +24227,0 +24228,0 +24229,0 +24230,0 +24231,0 +24232,0 +24233,0 +24234,0 +24235,0 +24236,0 +24237,0 +24238,0 +24239,0 +24240,0 +24241,0 +24242,0 +24243,0 +24244,0 +24245,0 +24246,0 +24247,0 +24248,0 +24249,0 +24250,0 +24251,0 +24252,0 +24253,0 +24254,0 +24255,0 +24256,0 +24257,0 +24258,0 +24259,0 +24260,0 +24261,0 +24262,0 +24263,0 +24264,0 +24265,0 +24266,0 +24267,0 +24268,0 +24269,0 +24270,0 +24271,0 +24272,0 +24273,0 +24274,0 +24275,0 +24276,0 +24277,0 +24278,0 +24279,0 +24280,0 +24281,0 +24282,0 +24283,0 +24284,0 +24285,0 +24286,0 +24287,0 +24288,0 +24289,0 +24290,0 +24291,0 +24292,0 +24293,0 +24294,0 +24295,0 +24296,0 +24297,0 +24298,0 +24299,0 +24300,0 +24301,0 +24302,0 +24303,0 +24304,0 +24305,0 +24306,0 +24307,0 +24308,0 +24309,0 +24310,0 +24311,0 +24312,0 +24313,0 +24314,0 +24315,0 +24316,0 +24317,0 +24318,0 +24319,0 +24320,0 +24321,0 +24322,0 +24323,0 +24324,0 +24325,0 +24326,0 +24327,0 +24328,0 +24329,0 +24330,0 +24331,0 +24332,0 +24333,0 +24334,0 +24335,0 +24336,0 +24337,0 +24338,0 +24339,0 +24340,0 +24341,0 +24342,0 +24343,0 +24344,0 +24345,0 +24346,0 +24347,0 +24348,0 +24349,0 +24350,0 +24351,0 +24352,0 +24353,0 +24354,0 +24355,0 +24356,0 +24357,0 +24358,0 +24359,0 +24360,0 +24361,0 +24362,0 +24363,0 +24364,0 +24365,0 +24366,0 +24367,0 +24368,0 +24369,0 +24370,0 +24371,0 +24372,0 +24373,0 +24374,0 +24375,0 +24376,0 +24377,0 +24378,0 +24379,0 +24380,0 +24381,0 +24382,0 +24383,0 +24384,0 +24385,0 +24386,0 +24387,0 +24388,0 +24389,0 +24390,0 +24391,0 +24392,0 +24393,0 +24394,0 +24395,0 +24396,0 +24397,0 +24398,0 +24399,0 +24400,0 +24401,0 +24402,0 +24403,0 +24404,0 +24405,0 +24406,0 +24407,0 +24408,0 +24409,0 +24410,0 +24411,0 +24412,0 +24413,0 +24414,0 +24415,0 +24416,0 +24417,0 +24418,0 +24419,0 +24420,0 +24421,0 +24422,0 +24423,0 +24424,0 +24425,0 +24426,0 +24427,0 +24428,0 +24429,0 +24430,0 +24431,0 +24432,0 +24433,0 +24434,0 +24435,0 +24436,0 +24437,0 +24438,0 +24439,0 +24440,0 +24441,0 +24442,0 +24443,0 +24444,0 +24445,0 +24446,0 +24447,0 +24448,0 +24449,0 +24450,0 +24451,0 +24452,0 +24453,0 +24454,0 +24455,0 +24456,0 +24457,0 +24458,0 +24459,0 +24460,0 +24461,0 +24462,0 +24463,0 +24464,0 +24465,0 +24466,0 +24467,0 +24468,0 +24469,0 +24470,0 +24471,0 +24472,0 +24473,0 +24474,0 +24475,0 +24476,0 +24477,0 +24478,0 +24479,0 +24480,0 +24481,0 +24482,0 +24483,0 +24484,0 +24485,0 +24486,0 +24487,0 +24488,0 +24489,0 +24490,0 +24491,0 +24492,0 +24493,0 +24494,0 +24495,0 +24496,0 +24497,0 +24498,0 +24499,0 +24500,0 +24501,0 +24502,0 +24503,0 +24504,0 +24505,0 +24506,0 +24507,0 +24508,0 +24509,0 +24510,0 +24511,0 +24512,0 +24513,0 +24514,0 +24515,0 +24516,0 +24517,0 +24518,0 +24519,0 +24520,0 +24521,0 +24522,0 +24523,0 +24524,0 +24525,0 +24526,0 +24527,0 +24528,0 +24529,0 +24530,0 +24531,0 +24532,0 +24533,0 +24534,0 +24535,0 +24536,0 +24537,0 +24538,0 +24539,0 +24540,0 +24541,0 +24542,0 +24543,0 +24544,0 +24545,0 +24546,0 +24547,0 +24548,0 +24549,0 +24550,0 +24551,0 +24552,0 +24553,0 +24554,0 +24555,0 +24556,0 +24557,0 +24558,0 +24559,0 +24560,0 +24561,0 +24562,0 +24563,0 +24564,0 +24565,0 +24566,0 +24567,0 +24568,0 +24569,0 +24570,0 +24571,0 +24572,0 +24573,0 +24574,0 +24575,0 +24576,0 +24577,0 +24578,0 +24579,0 +24580,0 +24581,0 +24582,0 +24583,0 +24584,0 +24585,0 +24586,0 +24587,0 +24588,0 +24589,0 +24590,0 +24591,0 +24592,0 +24593,0 +24594,0 +24595,0 +24596,0 +24597,0 +24598,0 +24599,0 +24600,0 +24601,0 +24602,0 +24603,0 +24604,0 +24605,0 +24606,0 +24607,0 +24608,0 +24609,0 +24610,0 +24611,0 +24612,0 +24613,0 +24614,0 +24615,0 +24616,0 +24617,0 +24618,0 +24619,0 +24620,0 +24621,0 +24622,0 +24623,0 +24624,0 +24625,0 +24626,0 +24627,0 +24628,0 +24629,0 +24630,0 +24631,0 +24632,0 +24633,0 +24634,0 +24635,0 +24636,0 +24637,0 +24638,0 +24639,0 +24640,0 +24641,0 +24642,0 +24643,0 +24644,0 +24645,0 +24646,0 +24647,0 +24648,0 +24649,0 +24650,0 +24651,0 +24652,0 +24653,0 +24654,0 +24655,0 +24656,0 +24657,0 +24658,0 +24659,0 +24660,0 +24661,0 +24662,0 +24663,0 +24664,0 +24665,0 +24666,0 +24667,0 +24668,0 +24669,0 +24670,0 +24671,0 +24672,0 +24673,0 +24674,0 +24675,0 +24676,0 +24677,0 +24678,0 +24679,0 +24680,0 +24681,0 +24682,0 +24683,0 +24684,0 +24685,0 +24686,0 +24687,0 +24688,0 +24689,0 +24690,0 +24691,0 +24692,0 +24693,0 +24694,0 +24695,0 +24696,0 +24697,0 +24698,0 +24699,0 +24700,0 +24701,0 +24702,0 +24703,0 +24704,0 +24705,0 +24706,0 +24707,0 +24708,0 +24709,0 +24710,0 +24711,0 +24712,0 +24713,0 +24714,0 +24715,0 +24716,0 +24717,0 +24718,0 +24719,0 +24720,0 +24721,0 +24722,0 +24723,0 +24724,0 +24725,0 +24726,0 +24727,0 +24728,0 +24729,0 +24730,0 +24731,0 +24732,0 +24733,0 +24734,0 +24735,0 +24736,0 +24737,0 +24738,0 +24739,0 +24740,0 +24741,0 +24742,0 +24743,0 +24744,0 +24745,0 +24746,0 +24747,0 +24748,0 +24749,0 +24750,0 +24751,0 +24752,0 +24753,0 +24754,0 +24755,0 +24756,0 +24757,0 +24758,0 +24759,0 +24760,0 +24761,0 +24762,0 +24763,0 +24764,0 +24765,0 +24766,0 +24767,0 +24768,0 +24769,0 +24770,0 +24771,0 +24772,0 +24773,0 +24774,0 +24775,0 +24776,0 +24777,0 +24778,0 +24779,0 +24780,0 +24781,0 +24782,0 +24783,0 +24784,0 +24785,0 +24786,0 +24787,0 +24788,0 +24789,0 +24790,0 +24791,0 +24792,0 +24793,0 +24794,0 +24795,0 +24796,0 +24797,0 +24798,0 +24799,0 +24800,0 +24801,0 +24802,0 +24803,0 +24804,0 +24805,0 +24806,0 +24807,0 +24808,0 +24809,0 +24810,0 +24811,0 +24812,0 +24813,0 +24814,0 +24815,0 +24816,0 +24817,0 +24818,0 +24819,0 +24820,0 +24821,0 +24822,0 +24823,0 +24824,0 +24825,0 +24826,0 +24827,0 +24828,0 +24829,0 +24830,0 +24831,0 +24832,0 +24833,0 +24834,0 +24835,0 +24836,0 +24837,0 +24838,0 +24839,0 +24840,0 +24841,0 +24842,0 +24843,0 +24844,0 +24845,0 +24846,0 +24847,0 +24848,0 +24849,0 +24850,0 +24851,0 +24852,0 +24853,0 +24854,0 +24855,0 +24856,0 +24857,0 +24858,0 +24859,0 +24860,0 +24861,0 +24862,0 +24863,0 +24864,0 +24865,0 +24866,0 +24867,0 +24868,0 +24869,0 +24870,0 +24871,0 +24872,0 +24873,0 +24874,0 +24875,0 +24876,0 +24877,0 +24878,0 +24879,0 +24880,0 +24881,0 +24882,0 +24883,0 +24884,0 +24885,0 +24886,0 +24887,0 +24888,0 +24889,0 +24890,0 +24891,0 +24892,0 +24893,0 +24894,0 +24895,0 +24896,0 +24897,0 +24898,0 +24899,0 +24900,0 +24901,0 +24902,0 +24903,0 +24904,0 +24905,0 +24906,0 +24907,0 +24908,0 +24909,0 +24910,0 +24911,0 +24912,0 +24913,0 +24914,0 +24915,0 +24916,0 +24917,0 +24918,0 +24919,0 +24920,0 +24921,0 +24922,0 +24923,0 +24924,0 +24925,0 +24926,0 +24927,0 +24928,0 +24929,0 +24930,0 +24931,0 +24932,0 +24933,0 +24934,0 +24935,0 +24936,0 +24937,0 +24938,0 +24939,0 +24940,0 +24941,0 +24942,0 +24943,0 +24944,0 +24945,0 +24946,0 +24947,0 +24948,0 +24949,0 +24950,0 +24951,0 +24952,0 +24953,0 +24954,0 +24955,0 +24956,0 +24957,0 +24958,0 +24959,0 +24960,0 +24961,0 +24962,0 +24963,0 +24964,0 +24965,0 +24966,0 +24967,0 +24968,0 +24969,0 +24970,0 +24971,0 +24972,0 +24973,0 +24974,0 +24975,0 +24976,0 +24977,0 +24978,0 +24979,0 +24980,0 +24981,0 +24982,0 +24983,0 +24984,0 +24985,0 +24986,0 +24987,0 +24988,0 +24989,0 +24990,0 +24991,0 +24992,0 +24993,0 +24994,0 +24995,0 +24996,0 +24997,0 +24998,0 +24999,0 +25000,0 +25001,0 +25002,0 +25003,0 +25004,0 +25005,0 +25006,0 +25007,0 +25008,0 +25009,0 +25010,0 +25011,0 +25012,0 +25013,0 +25014,0 +25015,0 +25016,0 +25017,0 +25018,0 +25019,0 +25020,0 +25021,0 +25022,0 +25023,0 +25024,0 +25025,0 +25026,0 +25027,0 +25028,0 +25029,0 +25030,0 +25031,0 +25032,0 +25033,0 +25034,0 +25035,0 +25036,0 +25037,0 +25038,0 +25039,0 +25040,0 +25041,0 +25042,0 +25043,0 +25044,0 +25045,0 +25046,0 +25047,0 +25048,0 +25049,0 +25050,0 +25051,0 +25052,0 +25053,0 +25054,0 +25055,0 +25056,0 +25057,0 +25058,0 +25059,0 +25060,0 +25061,0 +25062,0 +25063,0 +25064,0 +25065,0 +25066,0 +25067,0 +25068,0 +25069,0 +25070,0 +25071,0 +25072,0 +25073,0 +25074,0 +25075,0 +25076,0 +25077,0 +25078,0 +25079,0 +25080,0 +25081,0 +25082,0 +25083,0 +25084,0 +25085,0 +25086,0 +25087,0 +25088,0 +25089,0 +25090,0 +25091,0 +25092,0 +25093,0 +25094,0 +25095,0 +25096,0 +25097,0 +25098,0 +25099,0 +25100,0 +25101,0 +25102,0 +25103,0 +25104,0 +25105,0 +25106,0 +25107,0 +25108,0 +25109,0 +25110,0 +25111,0 +25112,0 +25113,0 +25114,0 +25115,0 +25116,0 +25117,0 +25118,0 +25119,0 +25120,0 +25121,0 +25122,0 +25123,0 +25124,0 +25125,0 +25126,0 +25127,0 +25128,0 +25129,0 +25130,0 +25131,0 +25132,0 +25133,0 +25134,0 +25135,0 +25136,0 +25137,0 +25138,0 +25139,0 +25140,0 +25141,0 +25142,0 +25143,0 +25144,0 +25145,0 +25146,0 +25147,0 +25148,0 +25149,0 +25150,0 +25151,0 +25152,0 +25153,0 +25154,0 +25155,0 +25156,0 +25157,0 +25158,0 +25159,0 +25160,0 +25161,0 +25162,0 +25163,0 +25164,0 +25165,0 +25166,0 +25167,0 +25168,0 +25169,0 +25170,0 +25171,0 +25172,0 +25173,0 +25174,0 +25175,0 +25176,0 +25177,0 +25178,0 +25179,0 +25180,0 +25181,0 +25182,0 +25183,0 +25184,0 +25185,0 +25186,0 +25187,0 +25188,0 +25189,0 +25190,0 +25191,0 +25192,0 +25193,0 +25194,0 +25195,0 +25196,0 +25197,0 +25198,0 +25199,0 +25200,0 +25201,0 +25202,0 +25203,0 +25204,0 +25205,0 +25206,0 +25207,0 +25208,0 +25209,0 +25210,0 +25211,0 +25212,0 +25213,0 +25214,0 +25215,0 +25216,0 +25217,0 +25218,0 +25219,0 +25220,0 +25221,0 +25222,0 +25223,0 +25224,0 +25225,0 +25226,0 +25227,0 +25228,0 +25229,0 +25230,0 +25231,0 +25232,0 +25233,0 +25234,0 +25235,0 +25236,0 +25237,0 +25238,0 +25239,0 +25240,0 +25241,0 +25242,0 +25243,0 +25244,0 +25245,0 +25246,0 +25247,0 +25248,0 +25249,0 +25250,0 +25251,0 +25252,0 +25253,0 +25254,0 +25255,0 +25256,0 +25257,0 +25258,0 +25259,0 +25260,0 +25261,0 +25262,0 +25263,0 +25264,0 +25265,0 +25266,0 +25267,0 +25268,0 +25269,0 +25270,0 +25271,0 +25272,0 +25273,0 +25274,0 +25275,0 +25276,0 +25277,0 +25278,0 +25279,0 +25280,0 +25281,0 +25282,0 +25283,0 +25284,0 +25285,0 +25286,0 +25287,0 +25288,0 +25289,0 +25290,0 +25291,0 +25292,0 +25293,0 +25294,0 +25295,0 +25296,0 +25297,0 +25298,0 +25299,0 +25300,0 +25301,0 +25302,0 +25303,0 +25304,0 +25305,0 +25306,0 +25307,0 +25308,0 +25309,0 +25310,0 +25311,0 +25312,0 +25313,0 +25314,0 +25315,0 +25316,0 +25317,0 +25318,0 +25319,0 +25320,0 +25321,0 +25322,0 +25323,0 +25324,0 +25325,0 +25326,0 +25327,0 +25328,0 +25329,0 +25330,0 +25331,0 +25332,0 +25333,0 +25334,0 +25335,0 +25336,0 +25337,0 +25338,0 +25339,0 +25340,0 +25341,0 +25342,0 +25343,0 +25344,0 +25345,0 +25346,0 +25347,0 +25348,0 +25349,0 +25350,0 +25351,0 +25352,0 +25353,0 +25354,0 +25355,0 +25356,0 +25357,0 +25358,0 +25359,0 +25360,0 +25361,0 +25362,0 +25363,0 +25364,0 +25365,0 +25366,0 +25367,0 +25368,0 +25369,0 +25370,0 +25371,0 +25372,0 +25373,0 +25374,0 +25375,0 +25376,0 +25377,0 +25378,0 +25379,0 +25380,0 +25381,0 +25382,0 +25383,0 +25384,0 +25385,0 +25386,0 +25387,0 +25388,0 +25389,0 +25390,0 +25391,0 +25392,0 +25393,0 +25394,0 +25395,0 +25396,0 +25397,0 +25398,0 +25399,0 +25400,0 +25401,0 +25402,0 +25403,0 +25404,0 +25405,0 +25406,0 +25407,0 +25408,0 +25409,0 +25410,0 +25411,0 +25412,0 +25413,0 +25414,0 +25415,0 +25416,0 +25417,0 +25418,0 +25419,0 +25420,0 +25421,0 +25422,0 +25423,0 +25424,0 +25425,0 +25426,0 +25427,0 +25428,0 +25429,0 +25430,0 +25431,0 +25432,0 +25433,0 +25434,0 +25435,0 +25436,0 +25437,0 +25438,0 +25439,0 +25440,0 +25441,0 +25442,0 +25443,0 +25444,0 +25445,0 +25446,0 +25447,0 +25448,0 +25449,0 +25450,0 +25451,0 +25452,0 +25453,0 +25454,0 +25455,0 +25456,0 +25457,0 +25458,0 +25459,0 +25460,0 +25461,0 +25462,0 +25463,0 +25464,0 +25465,0 +25466,0 +25467,0 +25468,0 +25469,0 +25470,0 +25471,0 +25472,0 +25473,0 +25474,0 +25475,0 +25476,0 +25477,0 +25478,0 +25479,0 +25480,0 +25481,0 +25482,0 +25483,0 +25484,0 +25485,0 +25486,0 +25487,0 +25488,0 +25489,0 +25490,0 +25491,0 +25492,0 +25493,0 +25494,0 +25495,0 +25496,0 +25497,0 +25498,0 +25499,0 +25500,0 +25501,0 +25502,0 +25503,0 +25504,0 +25505,0 +25506,0 +25507,0 +25508,0 +25509,0 +25510,0 +25511,0 +25512,0 +25513,0 +25514,0 +25515,0 +25516,0 +25517,0 +25518,0 +25519,0 +25520,0 +25521,0 +25522,0 +25523,0 +25524,0 +25525,0 +25526,0 +25527,0 +25528,0 +25529,0 +25530,0 +25531,0 +25532,0 +25533,0 +25534,0 +25535,0 +25536,0 +25537,0 +25538,0 +25539,0 +25540,0 +25541,0 +25542,0 +25543,0 +25544,0 +25545,0 +25546,0 +25547,0 +25548,0 +25549,0 +25550,0 +25551,0 +25552,0 +25553,0 +25554,0 +25555,0 +25556,0 +25557,0 +25558,0 +25559,0 +25560,0 +25561,0 +25562,0 +25563,0 +25564,0 +25565,0 +25566,0 +25567,0 +25568,0 +25569,0 +25570,0 +25571,0 +25572,0 +25573,0 +25574,0 +25575,0 +25576,0 +25577,0 +25578,0 +25579,0 +25580,0 +25581,0 +25582,0 +25583,0 +25584,0 +25585,0 +25586,0 +25587,0 +25588,0 +25589,0 +25590,0 +25591,0 +25592,0 +25593,0 +25594,0 +25595,0 +25596,0 +25597,0 +25598,0 +25599,0 +25600,0 +25601,0 +25602,0 +25603,0 +25604,0 +25605,0 +25606,0 +25607,0 +25608,0 +25609,0 +25610,0 +25611,0 +25612,0 +25613,0 +25614,0 +25615,0 +25616,0 +25617,0 +25618,0 +25619,0 +25620,0 +25621,0 +25622,0 +25623,0 +25624,0 +25625,0 +25626,0 +25627,0 +25628,0 +25629,0 +25630,0 +25631,0 +25632,0 +25633,0 +25634,0 +25635,0 +25636,0 +25637,0 +25638,0 +25639,0 +25640,0 +25641,0 +25642,0 +25643,0 +25644,0 +25645,0 +25646,0 +25647,0 +25648,0 +25649,0 +25650,0 +25651,0 +25652,0 +25653,0 +25654,0 +25655,0 +25656,0 +25657,0 +25658,0 +25659,0 +25660,0 +25661,0 +25662,0 +25663,0 +25664,0 +25665,0 +25666,0 +25667,0 +25668,0 +25669,0 +25670,0 +25671,0 +25672,0 +25673,0 +25674,0 +25675,0 +25676,0 +25677,0 +25678,0 +25679,0 +25680,0 +25681,0 +25682,0 +25683,0 +25684,0 +25685,0 +25686,0 +25687,0 +25688,0 +25689,0 +25690,0 +25691,0 +25692,0 +25693,0 +25694,0 +25695,0 +25696,0 +25697,0 +25698,0 +25699,0 +25700,0 +25701,0 +25702,0 +25703,0 +25704,0 +25705,0 +25706,0 +25707,0 +25708,0 +25709,0 +25710,0 +25711,0 +25712,0 +25713,0 +25714,0 +25715,0 +25716,0 +25717,0 +25718,0 +25719,0 +25720,0 +25721,0 +25722,0 +25723,0 +25724,0 +25725,0 +25726,0 +25727,0 +25728,0 +25729,0 +25730,0 +25731,0 +25732,0 +25733,0 +25734,0 +25735,0 +25736,0 +25737,0 +25738,0 +25739,0 +25740,0 +25741,0 +25742,0 +25743,0 +25744,0 +25745,0 +25746,0 +25747,0 +25748,0 +25749,0 +25750,0 +25751,0 +25752,0 +25753,0 +25754,0 +25755,0 +25756,0 +25757,0 +25758,0 +25759,0 +25760,0 +25761,0 +25762,0 +25763,0 +25764,0 +25765,0 +25766,0 +25767,0 +25768,0 +25769,0 +25770,0 +25771,0 +25772,0 +25773,0 +25774,0 +25775,0 +25776,0 +25777,0 +25778,0 +25779,0 +25780,0 +25781,0 +25782,0 +25783,0 +25784,0 +25785,0 +25786,0 +25787,0 +25788,0 +25789,0 +25790,0 +25791,0 +25792,0 +25793,0 +25794,0 +25795,0 +25796,0 +25797,0 +25798,0 +25799,0 +25800,0 +25801,0 +25802,0 +25803,0 +25804,0 +25805,0 +25806,0 +25807,0 +25808,0 +25809,0 +25810,0 +25811,0 +25812,0 +25813,0 +25814,0 +25815,0 +25816,0 +25817,0 +25818,0 +25819,0 +25820,0 +25821,0 +25822,0 +25823,0 +25824,0 +25825,0 +25826,0 +25827,0 +25828,0 +25829,0 +25830,0 +25831,0 +25832,0 +25833,0 +25834,0 +25835,0 +25836,0 +25837,0 +25838,0 +25839,0 +25840,0 +25841,0 +25842,0 +25843,0 +25844,0 +25845,0 +25846,0 +25847,0 +25848,0 +25849,0 +25850,0 +25851,0 +25852,0 +25853,0 +25854,0 +25855,0 +25856,0 +25857,0 +25858,0 +25859,0 +25860,0 +25861,0 +25862,0 +25863,0 +25864,0 +25865,0 +25866,0 +25867,0 +25868,0 +25869,0 +25870,0 +25871,0 +25872,0 +25873,0 +25874,0 +25875,0 +25876,0 +25877,0 +25878,0 +25879,0 +25880,0 +25881,0 +25882,0 +25883,0 +25884,0 +25885,0 +25886,0 +25887,0 +25888,0 +25889,0 +25890,0 +25891,0 +25892,0 +25893,0 +25894,0 +25895,0 +25896,0 +25897,0 +25898,0 +25899,0 +25900,0 +25901,0 +25902,0 +25903,0 +25904,0 +25905,0 +25906,0 +25907,0 +25908,0 +25909,0 +25910,0 +25911,0 +25912,0 +25913,0 +25914,0 +25915,0 +25916,0 +25917,0 +25918,0 +25919,0 +25920,0 +25921,0 +25922,0 +25923,0 +25924,0 +25925,0 +25926,0 +25927,0 +25928,0 +25929,0 +25930,0 +25931,0 +25932,0 +25933,0 +25934,0 +25935,0 +25936,0 +25937,0 +25938,0 +25939,0 +25940,0 +25941,0 +25942,0 +25943,0 +25944,0 +25945,0 +25946,0 +25947,0 +25948,0 +25949,0 +25950,0 +25951,0 +25952,0 +25953,0 +25954,0 +25955,0 +25956,0 +25957,0 +25958,0 +25959,0 +25960,0 +25961,0 +25962,0 +25963,0 +25964,0 +25965,0 +25966,0 +25967,0 +25968,0 +25969,0 +25970,0 +25971,0 +25972,0 +25973,0 +25974,0 +25975,0 +25976,0 +25977,0 +25978,0 +25979,0 +25980,0 +25981,0 +25982,0 +25983,0 +25984,0 +25985,0 +25986,0 +25987,0 +25988,0 +25989,0 +25990,0 +25991,0 +25992,0 +25993,0 +25994,0 +25995,0 +25996,0 +25997,0 +25998,0 +25999,0 +26000,0 +26001,0 +26002,0 +26003,0 +26004,0 +26005,0 +26006,0 +26007,0 +26008,0 +26009,0 +26010,0 +26011,0 +26012,0 +26013,0 +26014,0 +26015,0 +26016,0 +26017,0 +26018,0 +26019,0 +26020,0 +26021,0 +26022,0 +26023,0 +26024,0 +26025,0 +26026,0 +26027,0 +26028,0 +26029,0 +26030,0 +26031,0 +26032,0 +26033,0 +26034,0 +26035,0 +26036,0 +26037,0 +26038,0 +26039,0 +26040,0 +26041,0 +26042,0 +26043,0 +26044,0 +26045,0 +26046,0 +26047,0 +26048,0 +26049,0 +26050,0 +26051,0 +26052,0 +26053,0 +26054,0 +26055,0 +26056,0 +26057,0 +26058,0 +26059,0 +26060,0 +26061,0 +26062,0 +26063,0 +26064,0 +26065,0 +26066,0 +26067,0 +26068,0 +26069,0 +26070,0 +26071,0 +26072,0 +26073,0 +26074,0 +26075,0 +26076,0 +26077,0 +26078,0 +26079,0 +26080,0 +26081,0 +26082,0 +26083,0 +26084,0 +26085,0 +26086,0 +26087,0 +26088,0 +26089,0 +26090,0 +26091,0 +26092,0 +26093,0 +26094,0 +26095,0 +26096,0 +26097,0 +26098,0 +26099,0 +26100,0 +26101,0 +26102,0 +26103,0 +26104,0 +26105,0 +26106,0 +26107,0 +26108,0 +26109,0 +26110,0 +26111,0 +26112,0 +26113,0 +26114,0 +26115,0 +26116,0 +26117,0 +26118,0 +26119,0 +26120,0 +26121,0 +26122,0 +26123,0 +26124,0 +26125,0 +26126,0 +26127,0 +26128,0 +26129,0 +26130,0 +26131,0 +26132,0 +26133,0 +26134,0 +26135,0 +26136,0 +26137,0 +26138,0 +26139,0 +26140,0 +26141,0 +26142,0 +26143,0 +26144,0 +26145,0 +26146,0 +26147,0 +26148,0 +26149,0 +26150,0 +26151,0 +26152,0 +26153,0 +26154,0 +26155,0 +26156,0 +26157,0 +26158,0 +26159,0 +26160,0 +26161,0 +26162,0 +26163,0 +26164,0 +26165,0 +26166,0 +26167,0 +26168,0 +26169,0 +26170,0 +26171,0 +26172,0 +26173,0 +26174,0 +26175,0 +26176,0 +26177,0 +26178,0 +26179,0 +26180,0 +26181,0 +26182,0 +26183,0 +26184,0 +26185,0 +26186,0 +26187,0 +26188,0 +26189,0 +26190,0 +26191,0 +26192,0 +26193,0 +26194,0 +26195,0 +26196,0 +26197,0 +26198,0 +26199,0 +26200,0 +26201,0 +26202,0 +26203,0 +26204,0 +26205,0 +26206,0 +26207,0 +26208,0 +26209,0 +26210,0 +26211,0 +26212,0 +26213,0 +26214,0 +26215,0 +26216,0 +26217,0 +26218,0 +26219,0 +26220,0 +26221,0 +26222,0 +26223,0 +26224,0 +26225,0 +26226,0 +26227,0 +26228,0 +26229,0 +26230,0 +26231,0 +26232,0 +26233,0 +26234,0 +26235,0 +26236,0 +26237,0 +26238,0 +26239,0 +26240,0 +26241,0 +26242,0 +26243,0 +26244,0 +26245,0 +26246,0 +26247,0 +26248,0 +26249,0 +26250,0 +26251,0 +26252,0 +26253,0 +26254,0 +26255,0 +26256,0 +26257,0 +26258,0 +26259,0 +26260,0 +26261,0 +26262,0 +26263,0 +26264,0 +26265,0 +26266,0 +26267,0 +26268,0 +26269,0 +26270,0 +26271,0 +26272,0 +26273,0 +26274,0 +26275,0 +26276,0 +26277,0 +26278,0 +26279,0 +26280,0 +26281,0 +26282,0 +26283,0 +26284,0 +26285,0 +26286,0 +26287,0 +26288,0 +26289,0 +26290,0 +26291,0 +26292,0 +26293,0 +26294,0 +26295,0 +26296,0 +26297,0 +26298,0 +26299,0 +26300,0 +26301,0 +26302,0 +26303,0 +26304,0 +26305,0 +26306,0 +26307,0 +26308,0 +26309,0 +26310,0 +26311,0 +26312,0 +26313,0 +26314,0 +26315,0 +26316,0 +26317,0 +26318,0 +26319,0 +26320,0 +26321,0 +26322,0 +26323,0 +26324,0 +26325,0 +26326,0 +26327,0 +26328,0 +26329,0 +26330,0 +26331,0 +26332,0 +26333,0 +26334,0 +26335,0 +26336,0 +26337,0 +26338,0 +26339,0 +26340,0 +26341,0 +26342,0 +26343,0 +26344,0 +26345,0 +26346,0 +26347,0 +26348,0 +26349,0 +26350,0 +26351,0 +26352,0 +26353,0 +26354,0 +26355,0 +26356,0 +26357,0 +26358,0 +26359,0 +26360,0 +26361,0 +26362,0 +26363,0 +26364,0 +26365,0 +26366,0 +26367,0 +26368,0 +26369,0 +26370,0 +26371,0 +26372,0 +26373,0 +26374,0 +26375,0 +26376,0 +26377,0 +26378,0 +26379,0 +26380,0 +26381,0 +26382,0 +26383,0 +26384,0 +26385,0 +26386,0 +26387,0 +26388,0 +26389,0 +26390,0 +26391,0 +26392,0 +26393,0 +26394,0 +26395,0 +26396,0 +26397,0 +26398,0 +26399,0 +26400,0 +26401,0 +26402,0 +26403,0 +26404,0 +26405,0 +26406,0 +26407,0 +26408,0 +26409,0 +26410,0 +26411,0 +26412,0 +26413,0 +26414,0 +26415,0 +26416,0 +26417,0 +26418,0 +26419,0 +26420,0 +26421,0 +26422,0 +26423,0 +26424,0 +26425,0 +26426,0 +26427,0 +26428,0 +26429,0 +26430,0 +26431,0 +26432,0 +26433,0 +26434,0 +26435,0 +26436,0 +26437,0 +26438,0 +26439,0 +26440,0 +26441,0 +26442,0 +26443,0 +26444,0 +26445,0 +26446,0 +26447,0 +26448,0 +26449,0 +26450,0 +26451,0 +26452,0 +26453,0 +26454,0 +26455,0 +26456,0 +26457,0 +26458,0 +26459,0 +26460,0 +26461,0 +26462,0 +26463,0 +26464,0 +26465,0 +26466,0 +26467,0 +26468,0 +26469,0 +26470,0 +26471,0 +26472,0 +26473,0 +26474,0 +26475,0 +26476,0 +26477,0 +26478,0 +26479,0 +26480,0 +26481,0 +26482,0 +26483,0 +26484,0 +26485,0 +26486,0 +26487,0 +26488,0 +26489,0 +26490,0 +26491,0 +26492,0 +26493,0 +26494,0 +26495,0 +26496,0 +26497,0 +26498,0 +26499,0 +26500,0 +26501,0 +26502,0 +26503,0 +26504,0 +26505,0 +26506,0 +26507,0 +26508,0 +26509,0 +26510,0 +26511,0 +26512,0 +26513,0 +26514,0 +26515,0 +26516,0 +26517,0 +26518,0 +26519,0 +26520,0 +26521,0 +26522,0 +26523,0 +26524,0 +26525,0 +26526,0 +26527,0 +26528,0 +26529,0 +26530,0 +26531,0 +26532,0 +26533,0 +26534,0 +26535,0 +26536,0 +26537,0 +26538,0 +26539,0 +26540,0 +26541,0 +26542,0 +26543,0 +26544,0 +26545,0 +26546,0 +26547,0 +26548,0 +26549,0 +26550,0 +26551,0 +26552,0 +26553,0 +26554,0 +26555,0 +26556,0 +26557,0 +26558,0 +26559,0 +26560,0 +26561,0 +26562,0 +26563,0 +26564,0 +26565,0 +26566,0 +26567,0 +26568,0 +26569,0 +26570,0 +26571,0 +26572,0 +26573,0 +26574,0 +26575,0 +26576,0 +26577,0 +26578,0 +26579,0 +26580,0 +26581,0 +26582,0 +26583,0 +26584,0 +26585,0 +26586,0 +26587,0 +26588,0 +26589,0 +26590,0 +26591,0 +26592,0 +26593,0 +26594,0 +26595,0 +26596,0 +26597,0 +26598,0 +26599,0 +26600,0 +26601,0 +26602,0 +26603,0 +26604,0 +26605,0 +26606,0 +26607,0 +26608,0 +26609,0 +26610,0 +26611,0 +26612,0 +26613,0 +26614,0 +26615,0 +26616,0 +26617,0 +26618,0 +26619,0 +26620,0 +26621,0 +26622,0 +26623,0 +26624,0 +26625,0 +26626,0 +26627,0 +26628,0 +26629,0 +26630,0 +26631,0 +26632,0 +26633,0 +26634,0 +26635,0 +26636,0 +26637,0 +26638,0 +26639,0 +26640,0 +26641,0 +26642,0 +26643,0 +26644,0 +26645,0 +26646,0 +26647,0 +26648,0 +26649,0 +26650,0 +26651,0 +26652,0 +26653,0 +26654,0 +26655,0 +26656,0 +26657,0 +26658,0 +26659,0 +26660,0 +26661,0 +26662,0 +26663,0 +26664,0 +26665,0 +26666,0 +26667,0 +26668,0 +26669,0 +26670,0 +26671,0 +26672,0 +26673,0 +26674,0 +26675,0 +26676,0 +26677,0 +26678,0 +26679,0 +26680,0 +26681,0 +26682,0 +26683,0 +26684,0 +26685,0 +26686,0 +26687,0 +26688,0 +26689,0 +26690,0 +26691,0 +26692,0 +26693,0 +26694,0 +26695,0 +26696,0 +26697,0 +26698,0 +26699,0 +26700,0 +26701,0 +26702,0 +26703,0 +26704,0 +26705,0 +26706,0 +26707,0 +26708,0 +26709,0 +26710,0 +26711,0 +26712,0 +26713,0 +26714,0 +26715,0 +26716,0 +26717,0 +26718,0 +26719,0 +26720,0 +26721,0 +26722,0 +26723,0 +26724,0 +26725,0 +26726,0 +26727,0 +26728,0 +26729,0 +26730,0 +26731,0 +26732,0 +26733,0 +26734,0 +26735,0 +26736,0 +26737,0 +26738,0 +26739,0 +26740,0 +26741,0 +26742,0 +26743,0 +26744,0 +26745,0 +26746,0 +26747,0 +26748,0 +26749,0 +26750,0 +26751,0 +26752,0 +26753,0 +26754,0 +26755,0 +26756,0 +26757,0 +26758,0 +26759,0 +26760,0 +26761,0 +26762,0 +26763,0 +26764,0 +26765,0 +26766,0 +26767,0 +26768,0 +26769,0 +26770,0 +26771,0 +26772,0 +26773,0 +26774,0 +26775,0 +26776,0 +26777,0 +26778,0 +26779,0 +26780,0 +26781,0 +26782,0 +26783,0 +26784,0 +26785,0 +26786,0 +26787,0 +26788,0 +26789,0 +26790,0 +26791,0 +26792,0 +26793,0 +26794,0 +26795,0 +26796,0 +26797,0 +26798,0 +26799,0 +26800,0 +26801,0 +26802,0 +26803,0 +26804,0 +26805,0 +26806,0 +26807,0 +26808,0 +26809,0 +26810,0 +26811,0 +26812,0 +26813,0 +26814,0 +26815,0 +26816,0 +26817,0 +26818,0 +26819,0 +26820,0 +26821,0 +26822,0 +26823,0 +26824,0 +26825,0 +26826,0 +26827,0 +26828,0 +26829,0 +26830,0 +26831,0 +26832,0 +26833,0 +26834,0 +26835,0 +26836,0 +26837,0 +26838,0 +26839,0 +26840,0 +26841,0 +26842,0 +26843,0 +26844,0 +26845,0 +26846,0 +26847,0 +26848,0 +26849,0 +26850,0 +26851,0 +26852,0 +26853,0 +26854,0 +26855,0 +26856,0 +26857,0 +26858,0 +26859,0 +26860,0 +26861,0 +26862,0 +26863,0 +26864,0 +26865,0 +26866,0 +26867,0 +26868,0 +26869,0 +26870,0 +26871,0 +26872,0 +26873,0 +26874,0 +26875,0 +26876,0 +26877,0 +26878,0 +26879,0 +26880,0 +26881,0 +26882,0 +26883,0 +26884,0 +26885,0 +26886,0 +26887,0 +26888,0 +26889,0 +26890,0 +26891,0 +26892,0 +26893,0 +26894,0 +26895,0 +26896,0 +26897,0 +26898,0 +26899,0 +26900,0 +26901,0 +26902,0 +26903,0 +26904,0 +26905,0 +26906,0 +26907,0 +26908,0 +26909,0 +26910,0 +26911,0 +26912,0 +26913,0 +26914,0 +26915,0 +26916,0 +26917,0 +26918,0 +26919,0 +26920,0 +26921,0 +26922,0 +26923,0 +26924,0 +26925,0 +26926,0 +26927,0 +26928,0 +26929,0 +26930,0 +26931,0 +26932,0 +26933,0 +26934,0 +26935,0 +26936,0 +26937,0 +26938,0 +26939,0 +26940,0 +26941,0 +26942,0 +26943,0 +26944,0 +26945,0 +26946,0 +26947,0 +26948,0 +26949,0 +26950,0 +26951,0 +26952,0 +26953,0 +26954,0 +26955,0 +26956,0 +26957,0 +26958,0 +26959,0 +26960,0 +26961,0 +26962,0 +26963,0 +26964,0 +26965,0 +26966,0 +26967,0 +26968,0 +26969,0 +26970,0 +26971,0 +26972,0 +26973,0 +26974,0 +26975,0 +26976,0 +26977,0 +26978,0 +26979,0 +26980,0 +26981,0 +26982,0 +26983,0 +26984,0 +26985,0 +26986,0 +26987,0 +26988,0 +26989,0 +26990,0 +26991,0 +26992,0 +26993,0 +26994,0 +26995,0 +26996,0 +26997,0 +26998,0 +26999,0 +27000,0 +27001,0 +27002,0 +27003,0 +27004,0 +27005,0 +27006,0 +27007,0 +27008,0 +27009,0 +27010,0 +27011,0 +27012,0 +27013,0 +27014,0 +27015,0 +27016,0 +27017,0 +27018,0 +27019,0 +27020,0 +27021,0 +27022,0 +27023,0 +27024,0 +27025,0 +27026,0 +27027,0 +27028,0 +27029,0 +27030,0 +27031,0 +27032,0 +27033,0 +27034,0 +27035,0 +27036,0 +27037,0 +27038,0 +27039,0 +27040,0 +27041,0 +27042,0 +27043,0 +27044,0 +27045,0 +27046,0 +27047,0 +27048,0 +27049,0 +27050,0 +27051,0 +27052,0 +27053,0 +27054,0 +27055,0 +27056,0 +27057,0 +27058,0 +27059,0 +27060,0 +27061,0 +27062,0 +27063,0 +27064,0 +27065,0 +27066,0 +27067,0 +27068,0 +27069,0 +27070,0 +27071,0 +27072,0 +27073,0 +27074,0 +27075,0 +27076,0 +27077,0 +27078,0 +27079,0 +27080,0 +27081,0 +27082,0 +27083,0 +27084,0 +27085,0 +27086,0 +27087,0 +27088,0 +27089,0 +27090,0 +27091,0 +27092,0 +27093,0 +27094,0 +27095,0 +27096,0 +27097,0 +27098,0 +27099,0 +27100,0 +27101,0 +27102,0 +27103,0 +27104,0 +27105,0 +27106,0 +27107,0 +27108,0 +27109,0 +27110,0 +27111,0 +27112,0 +27113,0 +27114,0 +27115,0 +27116,0 +27117,0 +27118,0 +27119,0 +27120,0 +27121,0 +27122,0 +27123,0 +27124,0 +27125,0 +27126,0 +27127,0 +27128,0 +27129,0 +27130,0 +27131,0 +27132,0 +27133,0 +27134,0 +27135,0 +27136,0 +27137,0 +27138,0 +27139,0 +27140,0 +27141,0 +27142,0 +27143,0 +27144,0 +27145,0 +27146,0 +27147,0 +27148,0 +27149,0 +27150,0 +27151,0 +27152,0 +27153,0 +27154,0 +27155,0 +27156,0 +27157,0 +27158,0 +27159,0 +27160,0 +27161,0 +27162,0 +27163,0 +27164,0 +27165,0 +27166,0 +27167,0 +27168,0 +27169,0 +27170,0 +27171,0 +27172,0 +27173,0 +27174,0 +27175,0 +27176,0 +27177,0 +27178,0 +27179,0 +27180,0 +27181,0 +27182,0 +27183,0 +27184,0 +27185,0 +27186,0 +27187,0 +27188,0 +27189,0 +27190,0 +27191,0 +27192,0 +27193,0 +27194,0 +27195,0 +27196,0 +27197,0 +27198,0 +27199,0 +27200,0 +27201,0 +27202,0 +27203,0 +27204,0 +27205,0 +27206,0 +27207,0 +27208,0 +27209,0 +27210,0 +27211,0 +27212,0 +27213,0 +27214,0 +27215,0 +27216,0 +27217,0 +27218,0 +27219,0 +27220,0 +27221,0 +27222,0 +27223,0 +27224,0 +27225,0 +27226,0 +27227,0 +27228,0 +27229,0 +27230,0 +27231,0 +27232,0 +27233,0 +27234,0 +27235,0 +27236,0 +27237,0 +27238,0 +27239,0 +27240,0 +27241,0 +27242,0 +27243,0 +27244,0 +27245,0 +27246,0 +27247,0 +27248,0 +27249,0 +27250,0 +27251,0 +27252,0 +27253,0 +27254,0 +27255,0 +27256,0 +27257,0 +27258,0 +27259,0 +27260,0 +27261,0 +27262,0 +27263,0 +27264,0 +27265,0 +27266,0 +27267,0 +27268,0 +27269,0 +27270,0 +27271,0 +27272,0 +27273,0 +27274,0 +27275,0 +27276,0 +27277,0 +27278,0 +27279,0 +27280,0 +27281,0 +27282,0 +27283,0 +27284,0 +27285,0 +27286,0 +27287,0 +27288,0 +27289,0 +27290,0 +27291,0 +27292,0 +27293,0 +27294,0 +27295,0 +27296,0 +27297,0 +27298,0 +27299,0 +27300,0 +27301,0 +27302,0 +27303,0 +27304,0 +27305,0 +27306,0 +27307,0 +27308,0 +27309,0 +27310,0 +27311,0 +27312,0 +27313,0 +27314,0 +27315,0 +27316,0 +27317,0 +27318,0 +27319,0 +27320,0 +27321,0 +27322,0 +27323,0 +27324,0 +27325,0 +27326,0 +27327,0 +27328,0 +27329,0 +27330,0 +27331,0 +27332,0 +27333,0 +27334,0 +27335,0 +27336,0 +27337,0 +27338,0 +27339,0 +27340,0 +27341,0 +27342,0 +27343,0 +27344,0 +27345,0 +27346,0 +27347,0 +27348,0 +27349,0 +27350,0 +27351,0 +27352,0 +27353,0 +27354,0 +27355,0 +27356,0 +27357,0 +27358,0 +27359,0 +27360,0 +27361,0 +27362,0 +27363,0 +27364,0 +27365,0 +27366,0 +27367,0 +27368,0 +27369,0 +27370,0 +27371,0 +27372,0 +27373,0 +27374,0 +27375,0 +27376,0 +27377,0 +27378,0 +27379,0 +27380,0 +27381,0 +27382,0 +27383,0 +27384,0 +27385,0 +27386,0 +27387,0 +27388,0 +27389,0 +27390,0 +27391,0 +27392,0 +27393,0 +27394,0 +27395,0 +27396,0 +27397,0 +27398,0 +27399,0 +27400,0 +27401,0 +27402,0 +27403,0 +27404,0 +27405,0 +27406,0 +27407,0 +27408,0 +27409,0 +27410,0 +27411,0 +27412,0 +27413,0 +27414,0 +27415,0 +27416,0 +27417,0 +27418,0 +27419,0 +27420,0 +27421,0 +27422,0 +27423,0 +27424,0 +27425,0 +27426,0 +27427,0 +27428,0 +27429,0 +27430,0 +27431,0 +27432,0 +27433,0 +27434,0 +27435,0 +27436,0 +27437,0 +27438,0 +27439,0 +27440,0 +27441,0 +27442,0 +27443,0 +27444,0 +27445,0 +27446,0 +27447,0 +27448,0 +27449,0 +27450,0 +27451,0 +27452,0 +27453,0 +27454,0 +27455,0 +27456,0 +27457,0 +27458,0 +27459,0 +27460,0 +27461,0 +27462,0 +27463,0 +27464,0 +27465,0 +27466,0 +27467,0 +27468,0 +27469,0 +27470,0 +27471,0 +27472,0 +27473,0 +27474,0 +27475,0 +27476,0 +27477,0 +27478,0 +27479,0 +27480,0 +27481,0 +27482,0 +27483,0 +27484,0 +27485,0 +27486,0 +27487,0 +27488,0 +27489,0 +27490,0 +27491,0 +27492,0 +27493,0 +27494,0 +27495,0 +27496,0 +27497,0 +27498,0 +27499,0 +27500,0 +27501,0 +27502,0 +27503,0 +27504,0 +27505,0 +27506,0 +27507,0 +27508,0 +27509,0 +27510,0 +27511,0 +27512,0 +27513,0 +27514,0 +27515,0 +27516,0 +27517,0 +27518,0 +27519,0 +27520,0 +27521,0 +27522,0 +27523,0 +27524,0 +27525,0 +27526,0 +27527,0 +27528,0 +27529,0 +27530,0 +27531,0 +27532,0 +27533,0 +27534,0 +27535,0 +27536,0 +27537,0 +27538,0 +27539,0 +27540,0 +27541,0 +27542,0 +27543,0 +27544,0 +27545,0 +27546,0 +27547,0 +27548,0 +27549,0 +27550,0 +27551,0 +27552,0 +27553,0 +27554,0 +27555,0 +27556,0 +27557,0 +27558,0 +27559,0 +27560,0 +27561,0 +27562,0 +27563,0 +27564,0 +27565,0 +27566,0 +27567,0 +27568,0 +27569,0 +27570,0 +27571,0 +27572,0 +27573,0 +27574,0 +27575,0 +27576,0 +27577,0 +27578,0 +27579,0 +27580,0 +27581,0 +27582,0 +27583,0 +27584,0 +27585,0 +27586,0 +27587,0 +27588,0 +27589,0 +27590,0 +27591,0 +27592,0 +27593,0 +27594,0 +27595,0 +27596,0 +27597,0 +27598,0 +27599,0 +27600,0 +27601,0 +27602,0 +27603,0 +27604,0 +27605,0 +27606,0 +27607,0 +27608,0 +27609,0 +27610,0 +27611,0 +27612,0 +27613,0 +27614,0 +27615,0 +27616,0 +27617,0 +27618,0 +27619,0 +27620,0 +27621,0 +27622,0 +27623,0 +27624,0 +27625,0 +27626,0 +27627,0 +27628,0 +27629,0 +27630,0 +27631,0 +27632,0 +27633,0 +27634,0 +27635,0 +27636,0 +27637,0 +27638,0 +27639,0 +27640,0 +27641,0 +27642,0 +27643,0 +27644,0 +27645,0 +27646,0 +27647,0 +27648,0 +27649,0 +27650,0 +27651,0 +27652,0 +27653,0 +27654,0 +27655,0 +27656,0 +27657,0 +27658,0 +27659,0 +27660,0 +27661,0 +27662,0 +27663,0 +27664,0 +27665,0 +27666,0 +27667,0 +27668,0 +27669,0 +27670,0 +27671,0 +27672,0 +27673,0 +27674,0 +27675,0 +27676,0 +27677,0 +27678,0 +27679,0 +27680,0 +27681,0 +27682,0 +27683,0 +27684,0 +27685,0 +27686,0 +27687,0 +27688,0 +27689,0 +27690,0 +27691,0 +27692,0 +27693,0 +27694,0 +27695,0 +27696,0 +27697,0 +27698,0 +27699,0 +27700,0 +27701,0 +27702,0 +27703,0 +27704,0 +27705,0 +27706,0 +27707,0 +27708,0 +27709,0 +27710,0 +27711,0 +27712,0 +27713,0 +27714,0 +27715,0 +27716,0 +27717,0 +27718,0 +27719,0 +27720,0 +27721,0 +27722,0 +27723,0 +27724,0 +27725,0 +27726,0 +27727,0 +27728,0 +27729,0 +27730,0 +27731,0 +27732,0 +27733,0 +27734,0 +27735,0 +27736,0 +27737,0 +27738,0 +27739,0 +27740,0 +27741,0 +27742,0 +27743,0 +27744,0 +27745,0 +27746,0 +27747,0 +27748,0 +27749,0 +27750,0 +27751,0 +27752,0 +27753,0 +27754,0 +27755,0 +27756,0 +27757,0 +27758,0 +27759,0 +27760,0 +27761,0 +27762,0 +27763,0 +27764,0 +27765,0 +27766,0 +27767,0 +27768,0 +27769,0 +27770,0 +27771,0 +27772,0 +27773,0 +27774,0 +27775,0 +27776,0 +27777,0 +27778,0 +27779,0 +27780,0 +27781,0 +27782,0 +27783,0 +27784,0 +27785,0 +27786,0 +27787,0 +27788,0 +27789,0 +27790,0 +27791,0 +27792,0 +27793,0 +27794,0 +27795,0 +27796,0 +27797,0 +27798,0 +27799,0 +27800,0 +27801,0 +27802,0 +27803,0 +27804,0 +27805,0 +27806,0 +27807,0 +27808,0 +27809,0 +27810,0 +27811,0 +27812,0 +27813,0 +27814,0 +27815,0 +27816,0 +27817,0 +27818,0 +27819,0 +27820,0 +27821,0 +27822,0 +27823,0 +27824,0 +27825,0 +27826,0 +27827,0 +27828,0 +27829,0 +27830,0 +27831,0 +27832,0 +27833,0 +27834,0 +27835,0 +27836,0 +27837,0 +27838,0 +27839,0 +27840,0 +27841,0 +27842,0 +27843,0 +27844,0 +27845,0 +27846,0 +27847,0 +27848,0 +27849,0 +27850,0 +27851,0 +27852,0 +27853,0 +27854,0 +27855,0 +27856,0 +27857,0 +27858,0 +27859,0 +27860,0 +27861,0 +27862,0 +27863,0 +27864,0 +27865,0 +27866,0 +27867,0 +27868,0 +27869,0 +27870,0 +27871,0 +27872,0 +27873,0 +27874,0 +27875,0 +27876,0 +27877,0 +27878,0 +27879,0 +27880,0 +27881,0 +27882,0 +27883,0 +27884,0 +27885,0 +27886,0 +27887,0 +27888,0 +27889,0 +27890,0 +27891,0 +27892,0 +27893,0 +27894,0 +27895,0 +27896,0 +27897,0 +27898,0 +27899,0 +27900,0 +27901,0 +27902,0 +27903,0 +27904,0 +27905,0 +27906,0 +27907,0 +27908,0 +27909,0 +27910,0 +27911,0 +27912,0 +27913,0 +27914,0 +27915,0 +27916,0 +27917,0 +27918,0 +27919,0 +27920,0 +27921,0 +27922,0 +27923,0 +27924,0 +27925,0 +27926,0 +27927,0 +27928,0 +27929,0 +27930,0 +27931,0 +27932,0 +27933,0 +27934,0 +27935,0 +27936,0 +27937,0 +27938,0 +27939,0 +27940,0 +27941,0 +27942,0 +27943,0 +27944,0 +27945,0 +27946,0 +27947,0 +27948,0 +27949,0 +27950,0 +27951,0 +27952,0 +27953,0 +27954,0 +27955,0 +27956,0 +27957,0 +27958,0 +27959,0 +27960,0 +27961,0 +27962,0 +27963,0 +27964,0 +27965,0 +27966,0 +27967,0 +27968,0 +27969,0 +27970,0 +27971,0 +27972,0 +27973,0 +27974,0 +27975,0 +27976,0 +27977,0 +27978,0 +27979,0 +27980,0 +27981,0 +27982,0 +27983,0 +27984,0 +27985,0 +27986,0 +27987,0 +27988,0 +27989,0 +27990,0 +27991,0 +27992,0 +27993,0 +27994,0 +27995,0 +27996,0 +27997,0 +27998,0 +27999,0 +28000,0 diff --git a/digit-recognition-kaggle-competition/requirements.txt b/digit-recognition-kaggle-competition/requirements.txt index 92f270bc0..321b35785 100644 --- a/digit-recognition-kaggle-competition/requirements.txt +++ b/digit-recognition-kaggle-competition/requirements.txt @@ -1,4 +1,4 @@ -pandas==1.1.5 -seaborn==0.9.0 -tensorflow==2.3.0 -wget==3.2 +pandas==1.1.5 +seaborn==0.9.0 +tensorflow==2.3.0 +wget==3.2 diff --git a/facial-keypoints-detection-kaggle-competition/Readme.md b/facial-keypoints-detection-kaggle-competition/Readme.md index a283267c1..055077c16 100644 --- a/facial-keypoints-detection-kaggle-competition/Readme.md +++ b/facial-keypoints-detection-kaggle-competition/Readme.md @@ -1,198 +1,198 @@ -# Objective - -This example is based on the Facial Keypoints Detection Kaggle competition. The objective of this exercise is to predict keypoint positions on face images. - -## Environment - -This pipeline was tested using Kubeflow 1.4 and kfp 1.1.2 and x86-64 based system which includes all Intel and AMD based CPU's. ARM based systems are not supported. - -## Prerequisites for Building the Kubeflow Pipeline - -### Kubeflow - -It is assumed that you have Kubeflow installed. - -### Docker - -Docker is used to create an image to run each component in the pipeline. - -### Kubeflow Pipelines - -Kubeflow Pipelines connects each Docker-based component to create a pipeline. Each pipeline is a reproducible workflow wherein we pass input arguments and run the entire workflow. - -# Apply PodDefault resource - -## Step 1: Generate Kaggle API token -The input data needed to run this tutorial is been pulled from Kaggle . In order to pull the data we need to create a Kaggle account , user needs to register with his email and password and create a Kaggle username. - -Once we have successfully registered our Kaggle account. Now, we have to access the API Token . API access is needed to pull data from Kaggle , to get the API access go to you Kaggle profile and click on your profile picture on the top right we will see this option: - -Account - -Select “Account” from the menu. - -Scroll down to the “API” section and click “Create New API Token” : -Screenshot 2022-05-10 at 1 03 34 PM - - -This will download a file ‘kaggle.json’ with the following contents : -``` -username “My username” -key “My key” -``` -Now, substitute your “username” for `` and your “key” for  `` and create a Kubernetes secret using: 
 -``` -kubectl create secret generic kaggle-secret --from-literal=KAGGLE_USERNAME= --from-literal=KAGGLE_KEY= -``` - - -## Step2: Create a PodDefault resource - -We need a way to inject common data (env vars, volumes) to pods. In Kubeflow we use PodDefault resource which serves this usecase (reference: https://github.com/kubeflow/kubeflow/blob/master/components/admission-webhook/README.md). Using the PodDefault resource we can attach a secret to our data pulling step container which downloads data using Kaggle API. We create and apply PodDefault resource as follows : - -Create a `resource.yaml` file with the following code: - -``` -apiVersion: "kubeflow.org/v1alpha1" -kind: PodDefault -metadata: - name: kaggle-access -spec: - selector: - matchLabels: - kaggle-secret: "true" - desc: "kaggle-access" - volumeMounts: - - name: secret-volume - mountPath: /secret/kaggle - volumes: - - name: secret-volume - secret: - secretName: kaggle-secret -``` - -Apply the yaml with the following command: -``` -kubectl apply -f resource.yaml -``` - -# Build the Train and Evaluate images with Docker - -Kubeflow relies on Docker images to create pipelines. These images are pushed to a Docker container registry, from which Kubeflow accesses them. For the purposes of this how-to we are going to use Docker Hub as our registry. - -## Step 1: Log into Docker - -Start by creating a Docker account on DockerHub (https://hub.docker.com/). After signing up, Install Docker https://docs.docker.com/get-docker/ and enter `docker login` command on your terminal and enter your docker-hub username and password to log into Docker. - -## Step 2: Build the Train image - -Create a new build enviornment which contains Docker installed as highlighted in step1. After this in your new enviornment, on your terminal navigate to the pipeline-components/train/ directory and build the train Docker image using: -``` -$ cd pipeline-components/train/ -$ docker build -t /: . -``` -For example: -``` -$ docker build -t hubdocker76/demotrain:v8 . -``` -After building push the image using: -``` -$ docker push hubdocker76/demotrain:v8 -``` -## Step 3: Build the Evaluate image - -Next, on your docker enviornment go to terminal and navigate to the pipeline-components/eval/ directory and build the evaluate Docker image using: -``` -$ cd pipeline-components/eval/ -$ docker build -t /: . -``` -For example: -``` -$ docker build -t hubdocker76/demoeval:v3 . -``` -After building push the image using: -``` -$ docker push hubdocker76/demoeval:v3 -``` -## Kubeflow Pipeline - -As a needed step we create a virtual enviornment, that contains all components we need to convert our python code to yaml file. - -Steps to build a python virtual enviornment: - -Step a) Update pip -``` -python3 -m pip install --upgrade pip -``` - -Step b) Install virtualenv -``` -sudo pip3 install virtualenv -``` - -Step c) Check the installed version of venv -``` -virtualenv --version -``` - -Step d) Name your virtual enviornment as kfp -``` -virtualenv kfp -``` - -Step e) Activate your venv. -``` -source kfp/bin/activate -``` - -After this virtual environment will get activated. Now in our activated venv we need to install following packages: -``` -sudo apt-get update -sudo apt-get upgrade -sudo apt-get install -y git python3-pip - -python3 -m pip install kfp==1.1.2 -``` - -After installing packages create the yaml file - -Inside venv point your terminal to a path which contains our kfp file to build pipeline (facial-keypoints-detection-kfp.py) and run these commands: -``` -$ python3 facial-keypoints-detection-kfp.py -``` -…this will generate a yaml file: -``` -facial-keypoints-detection-kfp.py.yaml -``` - -## Run the Kubeflow Pipeline - -This `facial-keypoints-detection-kfp.py.yaml` file can then be uploaded to Kubeflow Pipelines UI from which you can create a Pipeline Run. The same yaml file will also be generated if we run the facial-keypoints-detection-kfp.ipynb notebook in the Notebook Server UI. - - -Upload file : -Screenshot 2022-05-23 at 10 08 40 PM - - -Create Run by selecting pipeline and give this run a name. Enter integer values for trial epoch and patience: -image - -Ideal values for trial epoch and patience are: trial=5, epoch=8, patience=3 - - -And then Start the Run. -Screenshot 2022-05-23 at 10 10 49 PM - - -# Kubeflow Pipeline with Kale - -To run this pipeline using the Kale JupyterLab extension, upload the `facial-keypoints-detection-kale.ipynb` file to your Kubeflow deployment where Kale is enabled. Once uploaded as a necessary step run the cell annotated with `skip` tag with function `download_kaggle_dataset`: - -Screenshot 2022-06-02 at 12 21 20 AM - - -This downloads the data using Kaggle API (use `` and `` as highlighted in `Apply PodDefault resource` step to get data using Kaggle API) this saves the download data to `my_data` folder. - -Only after the data is downloaded then click “compile and run” to create a pipeline run. - - +# Objective + +This example is based on the Facial Keypoints Detection Kaggle competition. The objective of this exercise is to predict keypoint positions on face images. + +## Environment + +This pipeline was tested using Kubeflow 1.4 and kfp 1.1.2 and x86-64 based system which includes all Intel and AMD based CPU's. ARM based systems are not supported. + +## Prerequisites for Building the Kubeflow Pipeline + +### Kubeflow + +It is assumed that you have Kubeflow installed. + +### Docker + +Docker is used to create an image to run each component in the pipeline. + +### Kubeflow Pipelines + +Kubeflow Pipelines connects each Docker-based component to create a pipeline. Each pipeline is a reproducible workflow wherein we pass input arguments and run the entire workflow. + +# Apply PodDefault resource + +## Step 1: Generate Kaggle API token +The input data needed to run this tutorial is been pulled from Kaggle . In order to pull the data we need to create a Kaggle account , user needs to register with his email and password and create a Kaggle username. + +Once we have successfully registered our Kaggle account. Now, we have to access the API Token . API access is needed to pull data from Kaggle , to get the API access go to you Kaggle profile and click on your profile picture on the top right we will see this option: + +Account + +Select “Account” from the menu. + +Scroll down to the “API” section and click “Create New API Token” : +Screenshot 2022-05-10 at 1 03 34 PM + + +This will download a file ‘kaggle.json’ with the following contents : +``` +username “My username” +key “My key” +``` +Now, substitute your “username” for `` and your “key” for  `` and create a Kubernetes secret using: 
 +``` +kubectl create secret generic kaggle-secret --from-literal=KAGGLE_USERNAME= --from-literal=KAGGLE_KEY= +``` + + +## Step2: Create a PodDefault resource + +We need a way to inject common data (env vars, volumes) to pods. In Kubeflow we use PodDefault resource which serves this usecase (reference: https://github.com/kubeflow/kubeflow/blob/master/components/admission-webhook/README.md). Using the PodDefault resource we can attach a secret to our data pulling step container which downloads data using Kaggle API. We create and apply PodDefault resource as follows : + +Create a `resource.yaml` file with the following code: + +``` +apiVersion: "kubeflow.org/v1alpha1" +kind: PodDefault +metadata: + name: kaggle-access +spec: + selector: + matchLabels: + kaggle-secret: "true" + desc: "kaggle-access" + volumeMounts: + - name: secret-volume + mountPath: /secret/kaggle + volumes: + - name: secret-volume + secret: + secretName: kaggle-secret +``` + +Apply the yaml with the following command: +``` +kubectl apply -f resource.yaml +``` + +# Build the Train and Evaluate images with Docker + +Kubeflow relies on Docker images to create pipelines. These images are pushed to a Docker container registry, from which Kubeflow accesses them. For the purposes of this how-to we are going to use Docker Hub as our registry. + +## Step 1: Log into Docker + +Start by creating a Docker account on DockerHub (https://hub.docker.com/). After signing up, Install Docker https://docs.docker.com/get-docker/ and enter `docker login` command on your terminal and enter your docker-hub username and password to log into Docker. + +## Step 2: Build the Train image + +Create a new build enviornment which contains Docker installed as highlighted in step1. After this in your new enviornment, on your terminal navigate to the pipeline-components/train/ directory and build the train Docker image using: +``` +$ cd pipeline-components/train/ +$ docker build -t /: . +``` +For example: +``` +$ docker build -t hubdocker76/demotrain:v8 . +``` +After building push the image using: +``` +$ docker push hubdocker76/demotrain:v8 +``` +## Step 3: Build the Evaluate image + +Next, on your docker enviornment go to terminal and navigate to the pipeline-components/eval/ directory and build the evaluate Docker image using: +``` +$ cd pipeline-components/eval/ +$ docker build -t /: . +``` +For example: +``` +$ docker build -t hubdocker76/demoeval:v3 . +``` +After building push the image using: +``` +$ docker push hubdocker76/demoeval:v3 +``` +## Kubeflow Pipeline + +As a needed step we create a virtual enviornment, that contains all components we need to convert our python code to yaml file. + +Steps to build a python virtual enviornment: + +Step a) Update pip +``` +python3 -m pip install --upgrade pip +``` + +Step b) Install virtualenv +``` +sudo pip3 install virtualenv +``` + +Step c) Check the installed version of venv +``` +virtualenv --version +``` + +Step d) Name your virtual enviornment as kfp +``` +virtualenv kfp +``` + +Step e) Activate your venv. +``` +source kfp/bin/activate +``` + +After this virtual environment will get activated. Now in our activated venv we need to install following packages: +``` +sudo apt-get update +sudo apt-get upgrade +sudo apt-get install -y git python3-pip + +python3 -m pip install kfp==1.1.2 +``` + +After installing packages create the yaml file + +Inside venv point your terminal to a path which contains our kfp file to build pipeline (facial-keypoints-detection-kfp.py) and run these commands: +``` +$ python3 facial-keypoints-detection-kfp.py +``` +…this will generate a yaml file: +``` +facial-keypoints-detection-kfp.py.yaml +``` + +## Run the Kubeflow Pipeline + +This `facial-keypoints-detection-kfp.py.yaml` file can then be uploaded to Kubeflow Pipelines UI from which you can create a Pipeline Run. The same yaml file will also be generated if we run the facial-keypoints-detection-kfp.ipynb notebook in the Notebook Server UI. + + +Upload file : +Screenshot 2022-05-23 at 10 08 40 PM + + +Create Run by selecting pipeline and give this run a name. Enter integer values for trial epoch and patience: +image + +Ideal values for trial epoch and patience are: trial=5, epoch=8, patience=3 + + +And then Start the Run. +Screenshot 2022-05-23 at 10 10 49 PM + + +# Kubeflow Pipeline with Kale + +To run this pipeline using the Kale JupyterLab extension, upload the `facial-keypoints-detection-kale.ipynb` file to your Kubeflow deployment where Kale is enabled. Once uploaded as a necessary step run the cell annotated with `skip` tag with function `download_kaggle_dataset`: + +Screenshot 2022-06-02 at 12 21 20 AM + + +This downloads the data using Kaggle API (use `` and `` as highlighted in `Apply PodDefault resource` step to get data using Kaggle API) this saves the download data to `my_data` folder. + +Only after the data is downloaded then click “compile and run” to create a pipeline run. + + diff --git a/facial-keypoints-detection-kaggle-competition/facial-keypoints-detection-kfp.py b/facial-keypoints-detection-kaggle-competition/facial-keypoints-detection-kfp.py index 258348513..b980763de 100644 --- a/facial-keypoints-detection-kaggle-competition/facial-keypoints-detection-kfp.py +++ b/facial-keypoints-detection-kaggle-competition/facial-keypoints-detection-kfp.py @@ -1,45 +1,45 @@ -import kfp -from kfp import dsl - - -def SendMsg(trial, epoch, patience): - vop = dsl.VolumeOp(name="pvc", - resource_name="pvc", size='5Gi', - modes=dsl.VOLUME_MODE_RWO) - - return dsl.ContainerOp( - name = 'Train', - image = 'hubdocker76/demotrain:v8', # use this prebuilt image or replace image with your own custom image - command = ['python3', 'train.py'], - arguments=[ - '--trial', trial, - '--epoch', epoch, - '--patience', patience - ], - pvolumes={ - '/data': vop.volume - } - ) - -def GetMsg(comp1): - return dsl.ContainerOp( - name = 'Evaluate', - image = 'hubdocker76/demoeval:v3', # use this prebuilt image or replace image with your own custom image - pvolumes={ - '/data': comp1.pvolumes['/data'] - }, - command = ['python3', 'eval.py'] - ) - -@dsl.pipeline( - name = 'face pipeline', - description = 'pipeline to detect facial landmarks') -def passing_parameter(trial, epoch, patience): - comp1 = SendMsg(trial, epoch, patience).add_pod_label("kaggle-secret", "true") - comp2 = GetMsg(comp1) - -if __name__ == '__main__': - import kfp.compiler as compiler - compiler.Compiler().compile(passing_parameter, __file__ + '.yaml') - - +import kfp +from kfp import dsl + + +def SendMsg(trial, epoch, patience): + vop = dsl.VolumeOp(name="pvc", + resource_name="pvc", size='5Gi', + modes=dsl.VOLUME_MODE_RWO) + + return dsl.ContainerOp( + name = 'Train', + image = 'hubdocker76/demotrain:v8', # use this prebuilt image or replace image with your own custom image + command = ['python3', 'train.py'], + arguments=[ + '--trial', trial, + '--epoch', epoch, + '--patience', patience + ], + pvolumes={ + '/data': vop.volume + } + ) + +def GetMsg(comp1): + return dsl.ContainerOp( + name = 'Evaluate', + image = 'hubdocker76/demoeval:v3', # use this prebuilt image or replace image with your own custom image + pvolumes={ + '/data': comp1.pvolumes['/data'] + }, + command = ['python3', 'eval.py'] + ) + +@dsl.pipeline( + name = 'face pipeline', + description = 'pipeline to detect facial landmarks') +def passing_parameter(trial, epoch, patience): + comp1 = SendMsg(trial, epoch, patience).add_pod_label("kaggle-secret", "true") + comp2 = GetMsg(comp1) + +if __name__ == '__main__': + import kfp.compiler as compiler + compiler.Compiler().compile(passing_parameter, __file__ + '.yaml') + + diff --git a/github_issue_summarization/Makefile b/github_issue_summarization/Makefile old mode 100755 new mode 100644 diff --git a/github_issue_summarization/pipelines/components/kubeflow-resources/containers/tf-serving-gh/build.sh b/github_issue_summarization/pipelines/components/kubeflow-resources/containers/tf-serving-gh/build.sh old mode 100755 new mode 100644 diff --git a/github_issue_summarization/pipelines/components/t2t/containers/base/build.sh b/github_issue_summarization/pipelines/components/t2t/containers/base/build.sh old mode 100755 new mode 100644 diff --git a/github_issue_summarization/pipelines/components/t2t/containers/metadata-logger/build.sh b/github_issue_summarization/pipelines/components/t2t/containers/metadata-logger/build.sh old mode 100755 new mode 100644 diff --git a/github_issue_summarization/pipelines/components/t2t/containers/t2t_app/build.sh b/github_issue_summarization/pipelines/components/t2t/containers/t2t_app/build.sh old mode 100755 new mode 100644 diff --git a/github_issue_summarization/pipelines/components/t2t/containers/t2t_proc/build.sh b/github_issue_summarization/pipelines/components/t2t/containers/t2t_proc/build.sh old mode 100755 new mode 100644 diff --git a/github_issue_summarization/pipelines/components/t2t/containers/t2t_train/build.sh b/github_issue_summarization/pipelines/components/t2t/containers/t2t_train/build.sh old mode 100755 new mode 100644 diff --git a/github_issue_summarization/pipelines/components/t2t/containers/webapp-launcher/build.sh b/github_issue_summarization/pipelines/components/t2t/containers/webapp-launcher/build.sh old mode 100755 new mode 100644 diff --git a/h-and-m-fash-rec-kaggle-competition/README.md b/h-and-m-fash-rec-kaggle-competition/README.md index 82a62d1c7..a8cfe1699 100644 --- a/h-and-m-fash-rec-kaggle-competition/README.md +++ b/h-and-m-fash-rec-kaggle-competition/README.md @@ -1,179 +1,179 @@ -# Kaggle Featured Prediction Competition: H&M Personalized Fashion Recommendations - -In this [competition](https://www.kaggle.com/competitions/h-and-m-personalized-fashion-recommendations), product recommendations have to be done based on previous purchases. There's a whole range of data available including customer meta data, product meta data, and meta data that spans from simple data, such as garment type and customer age, to text data from product descriptions, to image data from garment images. - -In this notebook we will be working with implicit's ALS library for our recommender systems. Please do check out the [docs](https://benfred.github.io/implicit/index.html) for more information. - -## Prerequisites for Building the Kubeflow Pipeline - -If you don’t already have Kubeflow up and running, we recommend signing up for a free trial of Arrikto's [Kubeflow as a Service](https://www.arrikto.com/kubeflow-as-a-service/). For the following example, we are using Kubeflow as a Service, but you should be able to run this example on any Kubeflow distribution. - -## Testing environment - -| Name | version | -| ------------- |:-------------:| -| Kubeflow | v1.4 | -| kfp | 1.8.11 | -| kubeflow-kale | 0.6.0 | - -## Initial Steps - -1. Please follow the Prerequisites section to get Kubeflow running. -2. Create a new Jupyter Notebook server with following resources - - CPU : 1 - - RAM : 32GB - - Workspace Volume : 50GB -3. Once you have the Jupyter Notebook server running, connect to it. -4. Clone this repo from the Terminal, so you have access to this directory. -5. Now before heading to Vanilla KFP steps, we need to save our Kaggle API credentials as a secret so that we can use the Kaggle Public [API](https://github.com/Kaggle/kaggle-api/blob/master/kaggle/api/kaggle_api_extended.py) to download the files from the Kaggle competition for our KFP/Kale pipeline. Following are the steps: - - If you are not a Kaggle user, you will first need to create a Kaggle account. After creation of the account, go to your Kaggle Account page and scroll down to API section. - -

- -

- - - Click on Create New API Token. A new API token in the form of kaggle.json file will be created which you can save locally. The kaggle.json file contains your Kaggle username and key. - - Once you have the API credentials, run the following command in the terminal with the username and key from the kaggle.json file that you just saved. - - ``` - kubectl create secret generic kaggle-secret --from-literal=KAGGLE_USERNAME= --from-literal=KAGGLE_KEY= - - ``` - This creates a secret for our credentials which can then be mounted on our pods. - - - Next create a yaml file with the following code in it. This would then be used to create a pod-default resource to mount the secret to any pod with a specific label(in our case kaggle-secret =true) - - ``` - apiVersion: "kubeflow.org/v1alpha1" - kind: PodDefault - metadata: - name: kaggle-access - spec: - selector: - matchLabels: - kaggle-secret: "true" - desc: "kaggle-access" - volumeMounts: - - name: secret-volume - mountPath: /secret/kaggle - volumes: - - name: secret-volume - secret: - secretName: kaggle-secret - - ``` - - To create a pod-default resource, run the following command, - - ``` - kubectl apply -f - - ``` - You can check out the following [link](https://support.arrikto.com/hc/en-us/articles/6335158153489-Acessing-External-System-with-User-Credentials-Kaggle-Example-) for more details about accessing external system with user credentials. -6. With the completion of 5th step, you are good to start with Vanilla KFP steps. - - - -## Vanilla KFP version - -To start building out a Kubeflow pipeline, you need to get yourself acquainted with the Kubeflow Pipelines [documentation](https://www.kubeflow.org/docs/components/pipelines/sdk/build-pipeline/) to understand what the pipelines are, its components, what goes into these components. There are different ways to build out a pipeline component as mentioned [here](https://www.kubeflow.org/docs/components/pipelines/sdk/build-pipeline/#building-pipeline-components). In the following example, we are going to use the [lightweight python functions](https://www.kubeflow.org/docs/components/pipelines/sdk/python-function-components/) based components for building up the pipeline. - -### Step 1: Install the Kubeflow Pipeline SDK and import the required kfp packages to run the pipeline - -From kfp, we will be using [func_to_container_op](https://kubeflow-pipelines.readthedocs.io/en/stable/source/kfp.components.html#kfp.components.func_to_container_op) which would help in building the factory function from the python function and we will use [InputPath](https://kubeflow-pipelines.readthedocs.io/en/stable/source/kfp.components.html#kfp.components.InputPath) and [OutputPath](https://kubeflow-pipelines.readthedocs.io/en/stable/source/kfp.components.html#kfp.components.OutputPath) from the components package to pass the paths of the files or models to these tasks. The [passing of data](https://www.kubeflow.org/docs/components/pipelines/sdk/python-function-components/#pass-data) is being implemented by kfp’s supported data passing mechanism. InputPath and OutputPath is how you pass on the data or model between the components. For [passing values](https://www.kubeflow.org/docs/components/pipelines/sdk/python-function-components/#passing-parameters-by-value), we are using NamedTuples which allows us to send multiple values between components. - -### Step 2: Next build out the pipeline components - -Our Kubeflow pipeline is broken down into five pipeline components: - -- Download the data from Kaggle -- Load and Preprocess the data -- Creating Sparse Matrix -- Train data -- Predictions - -We convert each python function to a factory function using the func_to_container_op which will then be converted to a pipeline task for our pipeline function. - -### Step 3 : Creating pipeline function - -After building all the pipeline components, we have to define a pipeline function connecting all the pipeline components with appropriate inputs and outputs. This when run would generate the pipeline graph. - -Pipeline function: - -

- -

- - -### Step 4 : Running the pipeline using the kfp.client instance - -There are different ways to run the pipeline function as mentioned in the [documentation](https://www.kubeflow.org/docs/components/pipelines/sdk/build-pipeline/#compile-and-run-your-pipeline). We would run the pipeline using the Kubeflow Pipelines SDK client. - -

- -

- -Once all the cells are executed successfully, you should see two hyperlinks ‘Experiment details’ and ‘Run details’. Click on ‘Run details’ link to observe the pipeline running. - -The final pipeline graph would look as follow: - -

- -

- -## Kale KFP version - -For the Kaggle notebook example, we are using [Kubeflow as a Service](https://www.arrikto.com/kubeflow-as-a-service/). If you are using Kubeflow as a Service then Kale comes preinstalled. For users with a different Kubeflow setup, you can refer to the [GitHub link](https://github.com/kubeflow-kale/kale#getting-started) for installing the Kale JupyterLab extension on your setup. - -### Step 1: Install all the required packages - -Run the first code cell to install all the required packages (not available under the standard python library) by using the requirements.txt file. Restart the kernel after installation. - -### Step 2: Download the data from Kaggle - -Run the second code cell to download the relevant data from Kaggle using the Kaggle Public API. You will require the API credentials from the kaggle.json file you got earlier in the Initial Steps. For the Kale notebook version, you don't have to create the secret, just need the API credentials to download the data. Once the code cell is run, you should see a new "data" directory being created with the zip files downloaded and unzipped. Please ensure that you run the cell only once so you don't create nested directories. Restart the kernel before running the code cell again. - -### Step 3: Annotate the notebook with Kale tags - -The Kale notebook in the directory is already annotated. To see the annotations, open up the Kale Deployment panel and click on the Enable switch button. Once you have it switched on, you should see the following: - -

- -

- -Please take time to understand how each cell is annotated by clicking on the cell and checking out the tag being used and what are is its dependencies. Kale provides us with six tags for annotations: - -- Imports -- Functions -- Pipeline Parameters -- Pipeline Metrics -- Pipeline Step -- Skip Cell - -You can also see the tags being created by checking out the Cell Metadata by clicking on the Property Inspector above the Kale Deployment Panel button. - -

- -

- -### Step 2: Run the Kubeflow Pipeline - -Once you’ve tagged your notebook, click on the “Compile and Run” button in the Kale widget. Kale will perform the following tasks for you: - -- Validate the notebook -- Take a snapshot -- Compile the notebook -- Upload the pipeline -- Run the pipeline - -In the “Running pipeline” output, click on the “View” hyperlink. This will take you directly to the runtime execution graph where you can watch your pipeline execute and update in real-time. - -

- -

- -## Note: -Both notebooks have been tested out and the whole pipeline run for both the Vanilla KFP and the Kale KFP versions take around 2hrs. Most of the time is being consumed in the predictions pipeline stage. In case of any error, please test out with the following docker image. - -Notebook server docker image used: gcr.io/arrikto/jupyter-kale-py36@sha256:dd3f92ca66b46d247e4b9b6a9d84ffbb368646263c2e3909473c3b851f3fe198 - -If the error persists, please raise an issue. +# Kaggle Featured Prediction Competition: H&M Personalized Fashion Recommendations + +In this [competition](https://www.kaggle.com/competitions/h-and-m-personalized-fashion-recommendations), product recommendations have to be done based on previous purchases. There's a whole range of data available including customer meta data, product meta data, and meta data that spans from simple data, such as garment type and customer age, to text data from product descriptions, to image data from garment images. + +In this notebook we will be working with implicit's ALS library for our recommender systems. Please do check out the [docs](https://benfred.github.io/implicit/index.html) for more information. + +## Prerequisites for Building the Kubeflow Pipeline + +If you don’t already have Kubeflow up and running, we recommend signing up for a free trial of Arrikto's [Kubeflow as a Service](https://www.arrikto.com/kubeflow-as-a-service/). For the following example, we are using Kubeflow as a Service, but you should be able to run this example on any Kubeflow distribution. + +## Testing environment + +| Name | version | +| ------------- |:-------------:| +| Kubeflow | v1.4 | +| kfp | 1.8.11 | +| kubeflow-kale | 0.6.0 | + +## Initial Steps + +1. Please follow the Prerequisites section to get Kubeflow running. +2. Create a new Jupyter Notebook server with following resources + - CPU : 1 + - RAM : 32GB + - Workspace Volume : 50GB +3. Once you have the Jupyter Notebook server running, connect to it. +4. Clone this repo from the Terminal, so you have access to this directory. +5. Now before heading to Vanilla KFP steps, we need to save our Kaggle API credentials as a secret so that we can use the Kaggle Public [API](https://github.com/Kaggle/kaggle-api/blob/master/kaggle/api/kaggle_api_extended.py) to download the files from the Kaggle competition for our KFP/Kale pipeline. Following are the steps: + - If you are not a Kaggle user, you will first need to create a Kaggle account. After creation of the account, go to your Kaggle Account page and scroll down to API section. + +

+ +

+ + - Click on Create New API Token. A new API token in the form of kaggle.json file will be created which you can save locally. The kaggle.json file contains your Kaggle username and key. + - Once you have the API credentials, run the following command in the terminal with the username and key from the kaggle.json file that you just saved. + + ``` + kubectl create secret generic kaggle-secret --from-literal=KAGGLE_USERNAME= --from-literal=KAGGLE_KEY= + + ``` + This creates a secret for our credentials which can then be mounted on our pods. + + - Next create a yaml file with the following code in it. This would then be used to create a pod-default resource to mount the secret to any pod with a specific label(in our case kaggle-secret =true) + + ``` + apiVersion: "kubeflow.org/v1alpha1" + kind: PodDefault + metadata: + name: kaggle-access + spec: + selector: + matchLabels: + kaggle-secret: "true" + desc: "kaggle-access" + volumeMounts: + - name: secret-volume + mountPath: /secret/kaggle + volumes: + - name: secret-volume + secret: + secretName: kaggle-secret + + ``` + - To create a pod-default resource, run the following command, + + ``` + kubectl apply -f + + ``` + You can check out the following [link](https://support.arrikto.com/hc/en-us/articles/6335158153489-Acessing-External-System-with-User-Credentials-Kaggle-Example-) for more details about accessing external system with user credentials. +6. With the completion of 5th step, you are good to start with Vanilla KFP steps. + + + +## Vanilla KFP version + +To start building out a Kubeflow pipeline, you need to get yourself acquainted with the Kubeflow Pipelines [documentation](https://www.kubeflow.org/docs/components/pipelines/sdk/build-pipeline/) to understand what the pipelines are, its components, what goes into these components. There are different ways to build out a pipeline component as mentioned [here](https://www.kubeflow.org/docs/components/pipelines/sdk/build-pipeline/#building-pipeline-components). In the following example, we are going to use the [lightweight python functions](https://www.kubeflow.org/docs/components/pipelines/sdk/python-function-components/) based components for building up the pipeline. + +### Step 1: Install the Kubeflow Pipeline SDK and import the required kfp packages to run the pipeline + +From kfp, we will be using [func_to_container_op](https://kubeflow-pipelines.readthedocs.io/en/stable/source/kfp.components.html#kfp.components.func_to_container_op) which would help in building the factory function from the python function and we will use [InputPath](https://kubeflow-pipelines.readthedocs.io/en/stable/source/kfp.components.html#kfp.components.InputPath) and [OutputPath](https://kubeflow-pipelines.readthedocs.io/en/stable/source/kfp.components.html#kfp.components.OutputPath) from the components package to pass the paths of the files or models to these tasks. The [passing of data](https://www.kubeflow.org/docs/components/pipelines/sdk/python-function-components/#pass-data) is being implemented by kfp’s supported data passing mechanism. InputPath and OutputPath is how you pass on the data or model between the components. For [passing values](https://www.kubeflow.org/docs/components/pipelines/sdk/python-function-components/#passing-parameters-by-value), we are using NamedTuples which allows us to send multiple values between components. + +### Step 2: Next build out the pipeline components + +Our Kubeflow pipeline is broken down into five pipeline components: + +- Download the data from Kaggle +- Load and Preprocess the data +- Creating Sparse Matrix +- Train data +- Predictions + +We convert each python function to a factory function using the func_to_container_op which will then be converted to a pipeline task for our pipeline function. + +### Step 3 : Creating pipeline function + +After building all the pipeline components, we have to define a pipeline function connecting all the pipeline components with appropriate inputs and outputs. This when run would generate the pipeline graph. + +Pipeline function: + +

+ +

+ + +### Step 4 : Running the pipeline using the kfp.client instance + +There are different ways to run the pipeline function as mentioned in the [documentation](https://www.kubeflow.org/docs/components/pipelines/sdk/build-pipeline/#compile-and-run-your-pipeline). We would run the pipeline using the Kubeflow Pipelines SDK client. + +

+ +

+ +Once all the cells are executed successfully, you should see two hyperlinks ‘Experiment details’ and ‘Run details’. Click on ‘Run details’ link to observe the pipeline running. + +The final pipeline graph would look as follow: + +

+ +

+ +## Kale KFP version + +For the Kaggle notebook example, we are using [Kubeflow as a Service](https://www.arrikto.com/kubeflow-as-a-service/). If you are using Kubeflow as a Service then Kale comes preinstalled. For users with a different Kubeflow setup, you can refer to the [GitHub link](https://github.com/kubeflow-kale/kale#getting-started) for installing the Kale JupyterLab extension on your setup. + +### Step 1: Install all the required packages + +Run the first code cell to install all the required packages (not available under the standard python library) by using the requirements.txt file. Restart the kernel after installation. + +### Step 2: Download the data from Kaggle + +Run the second code cell to download the relevant data from Kaggle using the Kaggle Public API. You will require the API credentials from the kaggle.json file you got earlier in the Initial Steps. For the Kale notebook version, you don't have to create the secret, just need the API credentials to download the data. Once the code cell is run, you should see a new "data" directory being created with the zip files downloaded and unzipped. Please ensure that you run the cell only once so you don't create nested directories. Restart the kernel before running the code cell again. + +### Step 3: Annotate the notebook with Kale tags + +The Kale notebook in the directory is already annotated. To see the annotations, open up the Kale Deployment panel and click on the Enable switch button. Once you have it switched on, you should see the following: + +

+ +

+ +Please take time to understand how each cell is annotated by clicking on the cell and checking out the tag being used and what are is its dependencies. Kale provides us with six tags for annotations: + +- Imports +- Functions +- Pipeline Parameters +- Pipeline Metrics +- Pipeline Step +- Skip Cell + +You can also see the tags being created by checking out the Cell Metadata by clicking on the Property Inspector above the Kale Deployment Panel button. + +

+ +

+ +### Step 2: Run the Kubeflow Pipeline + +Once you’ve tagged your notebook, click on the “Compile and Run” button in the Kale widget. Kale will perform the following tasks for you: + +- Validate the notebook +- Take a snapshot +- Compile the notebook +- Upload the pipeline +- Run the pipeline + +In the “Running pipeline” output, click on the “View” hyperlink. This will take you directly to the runtime execution graph where you can watch your pipeline execute and update in real-time. + +

+ +

+ +## Note: +Both notebooks have been tested out and the whole pipeline run for both the Vanilla KFP and the Kale KFP versions take around 2hrs. Most of the time is being consumed in the predictions pipeline stage. In case of any error, please test out with the following docker image. + +Notebook server docker image used: gcr.io/arrikto/jupyter-kale-py36@sha256:dd3f92ca66b46d247e4b9b6a9d84ffbb368646263c2e3909473c3b851f3fe198 + +If the error persists, please raise an issue. diff --git a/jpx-tokyo-stock-exchange-kaggle-competition/helper-files/local_api.py b/jpx-tokyo-stock-exchange-kaggle-competition/helper-files/local_api.py index 911c8d5d8..abe06fa8b 100644 --- a/jpx-tokyo-stock-exchange-kaggle-competition/helper-files/local_api.py +++ b/jpx-tokyo-stock-exchange-kaggle-competition/helper-files/local_api.py @@ -1,94 +1,94 @@ -import pandas as pd, os, numpy as np - -def calc_spread_return_per_day(df, portfolio_size, toprank_weight_ratio): - """ - Args: - df (pd.DataFrame): predicted results - portfolio_size (int): # of equities to buy/sell - toprank_weight_ratio (float): the relative weight of the most highly ranked stock compared to the least. - Returns: - (float): spread return - """ - assert df['Rank'].min() == 0 - assert df['Rank'].max() == len(df['Rank']) - 1 - weights = np.linspace(start=toprank_weight_ratio, stop=1, num=portfolio_size) - purchase = (df.sort_values(by='Rank')['Target'][:portfolio_size] * weights).sum() / weights.mean() - short = (df.sort_values(by='Rank', ascending=False)['Target'][:portfolio_size] * weights).sum() / weights.mean() - return purchase - short - -def calc_spread_return_sharpe(df: pd.DataFrame, portfolio_size: int = 200, toprank_weight_ratio: float = 2) -> float: - """ - Args: - df (pd.DataFrame): predicted results - portfolio_size (int): # of equities to buy/sell - toprank_weight_ratio (float): the relative weight of the most highly ranked stock compared to the least. - Returns: - (float): sharpe ratio - """ - buf = df.groupby('Date').apply(calc_spread_return_per_day, portfolio_size, toprank_weight_ratio) - sharpe_ratio = buf.mean() / buf.std() - return sharpe_ratio, buf - -class iter_test(): - def __init__(self, prices, options, financials, trades, secondary_prices, myapi): - self.myapi = myapi - self.dates = sorted(list(prices['Date'].unique())) - self.prices = prices.groupby('Date') - self.options = options.groupby('Date') - self.financials = financials.groupby('Date') - self.trades = trades.groupby('Date') - self.secondary_prices = secondary_prices.groupby('Date') - self.idx = 0 - def __next__(self): - if self.idx == len(self.dates): - self.myapi.submission = pd.concat(self.myapi.submission) - os.getcwd() - self.myapi.submission.to_csv('local_submission.csv', index=False) - self.idx = 0 - raise StopIteration - else: - prices = self.prices.get_group(self.dates[self.idx]) - options = self.options.get_group(self.dates[self.idx]) - financials = self.financials.get_group(self.dates[self.idx]) - trades = self.trades.get_group(self.dates[self.idx]) - secondary_prices = self.secondary_prices.get_group(self.dates[self.idx]) - sample_submission = pd.DataFrame(prices['Date'].copy(), columns = ['Date']) - sample_submission['SecuritiesCode'] = prices['SecuritiesCode'].copy() - self.idx += 1 - return prices, options, financials, trades, secondary_prices, sample_submission.reset_index(drop=True) - def __iter__(self): - return self - def __len__(self): - return len(self.dates) - -class local_api(): - def __init__(self, data_dir, start_date='2021-12-06', end_date='2022-02-28'): - """ - This module simulates the online API in a local environment, in order for people to estimate running time and memory. - Parameters: - data_dir: directory in which data files are stored. - start_date: str, evaluation starting date. - end_date: str, evaluation ending date. - """ - self.prices = pd.read_csv(os.path.join(data_dir, 'stock_prices.csv')) - self.options = pd.read_csv(os.path.join(data_dir, 'options.csv')) - self.financials = pd.read_csv(os.path.join(data_dir, 'financials.csv')) - self.trades = pd.read_csv(os.path.join(data_dir, 'trades.csv')) - self.secondary_prices = pd.read_csv(os.path.join(data_dir, 'secondary_stock_prices.csv')) - self.prices = self.prices.loc[(self.prices['Date'] >= start_date) & (self.prices['Date'] <= end_date)] - self.options = self.options.loc[(self.options['Date'] >= start_date) & (self.options['Date'] <= end_date)] - self.financials = self.financials.loc[(self.financials['Date'] >= start_date) & (self.financials['Date'] <= end_date)] - self.trades = self.trades.loc[(self.trades['Date'] >= start_date) & (self.trades['Date'] <= end_date)] - self.secondary_prices = self.secondary_prices.loc[(self.secondary_prices['Date'] >= start_date) &\ - (self.secondary_prices['Date'] <= end_date)] - self.gt_prices = self.prices[['Date', 'SecuritiesCode', 'Target']].copy() - self.prices.drop(['Target'], inplace=True, axis = 1) - def make_env(self): - return self - def iter_test(self): - self.submission = [] - return iter_test(self.prices, self.options, self.financials, self.trades, self.secondary_prices, self) - def predict(self, prediction): - self.submission.append(prediction) - def score(self): +import pandas as pd, os, numpy as np + +def calc_spread_return_per_day(df, portfolio_size, toprank_weight_ratio): + """ + Args: + df (pd.DataFrame): predicted results + portfolio_size (int): # of equities to buy/sell + toprank_weight_ratio (float): the relative weight of the most highly ranked stock compared to the least. + Returns: + (float): spread return + """ + assert df['Rank'].min() == 0 + assert df['Rank'].max() == len(df['Rank']) - 1 + weights = np.linspace(start=toprank_weight_ratio, stop=1, num=portfolio_size) + purchase = (df.sort_values(by='Rank')['Target'][:portfolio_size] * weights).sum() / weights.mean() + short = (df.sort_values(by='Rank', ascending=False)['Target'][:portfolio_size] * weights).sum() / weights.mean() + return purchase - short + +def calc_spread_return_sharpe(df: pd.DataFrame, portfolio_size: int = 200, toprank_weight_ratio: float = 2) -> float: + """ + Args: + df (pd.DataFrame): predicted results + portfolio_size (int): # of equities to buy/sell + toprank_weight_ratio (float): the relative weight of the most highly ranked stock compared to the least. + Returns: + (float): sharpe ratio + """ + buf = df.groupby('Date').apply(calc_spread_return_per_day, portfolio_size, toprank_weight_ratio) + sharpe_ratio = buf.mean() / buf.std() + return sharpe_ratio, buf + +class iter_test(): + def __init__(self, prices, options, financials, trades, secondary_prices, myapi): + self.myapi = myapi + self.dates = sorted(list(prices['Date'].unique())) + self.prices = prices.groupby('Date') + self.options = options.groupby('Date') + self.financials = financials.groupby('Date') + self.trades = trades.groupby('Date') + self.secondary_prices = secondary_prices.groupby('Date') + self.idx = 0 + def __next__(self): + if self.idx == len(self.dates): + self.myapi.submission = pd.concat(self.myapi.submission) + os.getcwd() + self.myapi.submission.to_csv('local_submission.csv', index=False) + self.idx = 0 + raise StopIteration + else: + prices = self.prices.get_group(self.dates[self.idx]) + options = self.options.get_group(self.dates[self.idx]) + financials = self.financials.get_group(self.dates[self.idx]) + trades = self.trades.get_group(self.dates[self.idx]) + secondary_prices = self.secondary_prices.get_group(self.dates[self.idx]) + sample_submission = pd.DataFrame(prices['Date'].copy(), columns = ['Date']) + sample_submission['SecuritiesCode'] = prices['SecuritiesCode'].copy() + self.idx += 1 + return prices, options, financials, trades, secondary_prices, sample_submission.reset_index(drop=True) + def __iter__(self): + return self + def __len__(self): + return len(self.dates) + +class local_api(): + def __init__(self, data_dir, start_date='2021-12-06', end_date='2022-02-28'): + """ + This module simulates the online API in a local environment, in order for people to estimate running time and memory. + Parameters: + data_dir: directory in which data files are stored. + start_date: str, evaluation starting date. + end_date: str, evaluation ending date. + """ + self.prices = pd.read_csv(os.path.join(data_dir, 'stock_prices.csv')) + self.options = pd.read_csv(os.path.join(data_dir, 'options.csv')) + self.financials = pd.read_csv(os.path.join(data_dir, 'financials.csv')) + self.trades = pd.read_csv(os.path.join(data_dir, 'trades.csv')) + self.secondary_prices = pd.read_csv(os.path.join(data_dir, 'secondary_stock_prices.csv')) + self.prices = self.prices.loc[(self.prices['Date'] >= start_date) & (self.prices['Date'] <= end_date)] + self.options = self.options.loc[(self.options['Date'] >= start_date) & (self.options['Date'] <= end_date)] + self.financials = self.financials.loc[(self.financials['Date'] >= start_date) & (self.financials['Date'] <= end_date)] + self.trades = self.trades.loc[(self.trades['Date'] >= start_date) & (self.trades['Date'] <= end_date)] + self.secondary_prices = self.secondary_prices.loc[(self.secondary_prices['Date'] >= start_date) &\ + (self.secondary_prices['Date'] <= end_date)] + self.gt_prices = self.prices[['Date', 'SecuritiesCode', 'Target']].copy() + self.prices.drop(['Target'], inplace=True, axis = 1) + def make_env(self): + return self + def iter_test(self): + self.submission = [] + return iter_test(self.prices, self.options, self.financials, self.trades, self.secondary_prices, self) + def predict(self, prediction): + self.submission.append(prediction) + def score(self): return calc_spread_return_sharpe(self.submission.merge(self.gt_prices))[0] \ No newline at end of file diff --git a/mnist/Makefile b/mnist/Makefile old mode 100755 new mode 100644 diff --git a/named_entity_recognition/components/build_components.sh b/named_entity_recognition/components/build_components.sh old mode 100755 new mode 100644 diff --git a/named_entity_recognition/components/copy_specification.sh b/named_entity_recognition/components/copy_specification.sh old mode 100755 new mode 100644 diff --git a/named_entity_recognition/components/deploy/build_image.sh b/named_entity_recognition/components/deploy/build_image.sh old mode 100755 new mode 100644 diff --git a/named_entity_recognition/components/preprocess/build_image.sh b/named_entity_recognition/components/preprocess/build_image.sh old mode 100755 new mode 100644 diff --git a/named_entity_recognition/components/train/build_image.sh b/named_entity_recognition/components/train/build_image.sh old mode 100755 new mode 100644 diff --git a/named_entity_recognition/routine/build_routine.sh b/named_entity_recognition/routine/build_routine.sh old mode 100755 new mode 100644 diff --git a/natural-language-processing-with-disaster-tweets-kaggle-competition/requirements.txt b/natural-language-processing-with-disaster-tweets-kaggle-competition/requirements.txt index ddca17cf1..06eef5368 100644 --- a/natural-language-processing-with-disaster-tweets-kaggle-competition/requirements.txt +++ b/natural-language-processing-with-disaster-tweets-kaggle-competition/requirements.txt @@ -1,7 +1,7 @@ -matplotlib==3.3.4 -seaborn==0.9.0 -nltk==3.6.7 -scikit-learn==0.23.2 -gensim==4.2.0 -tensorflow==2.3.0 -wget==3.2 +matplotlib==3.3.4 +seaborn==0.9.0 +nltk==3.6.7 +scikit-learn==0.23.2 +gensim==4.2.0 +tensorflow==2.3.0 +wget==3.2 diff --git a/object_detection/ks-app/environments/base.libsonnet b/object_detection/ks-app/environments/base.libsonnet deleted file mode 100644 index a129affb1..000000000 --- a/object_detection/ks-app/environments/base.libsonnet +++ /dev/null @@ -1,4 +0,0 @@ -local components = std.extVar("__ksonnet/components"); -components + { - // Insert user-specified overrides here. -} diff --git a/openvaccine-kaggle-competition/Readme.md b/openvaccine-kaggle-competition/Readme.md index 11ccd4414..35c194050 100644 --- a/openvaccine-kaggle-competition/Readme.md +++ b/openvaccine-kaggle-competition/Readme.md @@ -1,378 +1,378 @@ -# Objective - -This example is based on the Titanic OpenVaccine competition (https://www.kaggle.com/c/stanford-covid-vaccine). The objective of this exercise is to develop models and design rules for RNA degradation. - -## Environment - -This pipeline was tested using Kubeflow 1.4 and kfp 1.1.2 and x86-64 and ARM based system which includes all Intel and AMD based CPU's and M1/M2 series Macbooks. - -## Step 1: Setup Kubeflow as a Service - -- If you haven’t already, sign up (https://www.arrikto.com/kubeflow-as-a-service/) -- Deploy Kubeflow - -## Step 2: Launch a Notebook Server - -- Bump memory to 2GB and vCPUs to 2 - -## Step 3: Clone the Project Repo to Your Notebook - -- (Kubeflow as a Service) Open up a terminal in the Notebook Server and git clone the `kubeflow/examples` repository -``` -git clone https://github.com/kubeflow/examples -``` -## Step 4: Setup DockerHub and Docker - -- If you haven’t already, sign up (https://hub.docker.com/) for DockerHub -- If you haven’t already, install Docker Desktop locally (https://www.docker.com/products/docker-desktop/) OR install the Docker command line utility (https://docs.docker.com/get-docker/) and enter `sudo docker login` command in your terminal and log into Docker with your your DockerHub username and password - - -## Step 5: Setup Kaggle - -- If you haven’t already done so, sign up (https://www.kaggle.com/) for Kaggle -- (On Kaggle) Generate an API token (https://www.kaggle.com/docs/api) -- (Kubeflow as a Service) Create a Kubernetes secret - -``` -kubectl create secret generic kaggle-secret --from-literal=KAGGLE_USERNAME= --from-literal=KAGGLE_KEY= -``` - -## Step 6: Install Git - -- (Locally) If you don’t have it already, install Git (https://github.com/git-guides/install-git) - -## Step 7: Clone the Project Repo Locally - -- (Locally) Git clone the `kubeflow/examples` repository -``` -git clone https://github.com/kubeflow/examples -``` - -## Step 8: Create a PodDefault Resource - -- (Kubeflow as a Service) Navigate to the `openvaccine-kaggle-competition` directory -- Create a `resource.yaml` file - -resource.yaml: -``` -apiVersion: "kubeflow.org/v1alpha1" -kind: PodDefault -metadata: - name: kaggle-access -spec: - selector: - matchLabels: - kaggle-secret: "true" - desc: "kaggle-access" - volumeMounts: - - name: secret-volume - mountPath: /secret/kaggle - volumes: - - name: secret-volume - secret: - secretName: kaggle-secret -``` - -![image2](https://user-images.githubusercontent.com/17012391/177001253-3e525eb6-3415-428c-a52b-11803326af6b.png) - -- Apply created resource using: `kubectl apply -f resource.yaml` - -## Step 9: Explore the `load-data` directory - -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/load-data` directory -- Open up the `load.py` file -- Note the code in this file that will perform the actions required in the “load-data” pipeline step - -image7 - -## Step 10: Build the `load-data` Docker Image - -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/load-data` directory -- Build the Docker image if locally you are using arm64 (Apple M1) - -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` - -## Step 11: Push the `load-data` Docker Image to DockerHub - -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/load-data` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` - -## Step 12: Explore the `preprocess-data` directory - -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/preprocess-data` directory -- Open up the `preprocess.py` file -- Note the code in this file that will perform the actions required in the “preprocess” pipeline step - -image5 - - -## Step 13: Explore the `preprocess-data` directory -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/preprocess-data` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` - -## Step 14: Push the `preprocess-data` Docker Image to DockerHub - -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/preprocess-data` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` - -## Step 15: Explore the `model-training` directory - -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-training` directory -- Open up the `model.py` file -- Note the code in this file that will perform the actions required in the “train” pipeline step - -![image4](https://user-images.githubusercontent.com/17012391/177001740-a63f190c-284e-4328-ba01-17dbdbe61cee.png) - -## Step 16: Build the `model-training` Docker Image - -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-training` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` - -## Step 17: Push the `model-training` Docker Image to DockerHub - -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-training` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` - -## Step 18: Explore the `model-evaluation` directory - -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-evaluation` directory -- Open up the `eval.py` file -- Note the code in this file that will perform the actions required in the “test” pipeline step - -![image1](https://user-images.githubusercontent.com/17012391/177001951-1f7b13b9-adea-48c1-89a7-d8dc67214133.png) - - -## Step 19: Build the `model-evaluation` Docker Image - -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-evaluation` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` - -## Step 20: Push the `model-evaluation` Docker Image to DockerHub - -- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-evaluation` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` -## Step 21: Modify the openvaccine-kaggle-competiton-kfp.py file - -- (Kubeflow as a Service) Navigate to the `openvaccine-kaggle-competition` directory -- Update the `openvaccine-kaggle-competiton-kfp.py` with accurate Docker Image inputs - -``` - return dsl.ContainerOp( - name = 'load-data', - image = '/:', - -—----- - -def GetMsg(comp1): - return dsl.ContainerOp( - name = 'preprocess', - image = '/:', - -—----- - -def Train(comp2, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength): - return dsl.ContainerOp( - name = 'train', - image = '/:', - -—----- - -def Eval(comp1, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength): - return dsl.ContainerOp( - name = 'Evaluate', - image = '/:', -``` - -## Step 22: Generate a KFP Pipeline yaml File - -- (Locally) Navigate to the `openvaccine-kaggle-competition` directory and delete the existing `openvaccine-kaggle-competition-kfp.yaml` file -- (Kubeflow as a Service) Navigate to the openvaccine-kaggle-competition directory - -Build a python virtual environment : - - -Step a) Update pip -``` -python3 -m pip install --upgrade pip -``` - -Step b) Install virtualenv -``` -sudo pip3 install virtualenv -``` - -Step c) Check the installed version of venv -``` -virtualenv --version -``` - -Step d) Name your virtual enviornment as kfp -``` -virtualenv kfp -``` - -Step e) Activate your venv. -``` -source kfp/bin/activate -``` - -After this virtual environment will get activated. Now in our activated venv we need to install following packages: -``` -sudo apt-get update -sudo apt-get upgrade -sudo apt-get install -y git python3-pip - -python3 -m pip install kfp==1.1.2 -``` - -After installing packages create the yaml file - -Inside venv point your terminal to a path which contains our kfp file to build pipeline (openvaccine-kaggle-competition-kfp.py) and run these commands to generate a `yaml` file for the Pipeline: - -``` -python3 openvaccine-kaggle-competition-kfp.py -``` -image3 - -Download the `openvaccine-kaggle-competition-kfp.yaml` file that was created to your local `openvaccine-kaggle-competition` directory - -## Step 23: Create an Experiment - -- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Experiments (KFP) > Create Experiment view -- Name the experiment and click Next -- Click on Experiments (KFP) to view the experiment you just created - -## Step 24: Create a Pipeline - - -- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Pipelines > +Upload Pipeline view -- Name the pipeline -- Click on Upload a file -- Upload the local `openvaccine-kaggle-competition-kfp.yaml` file -- Click Create - -## Step 25: Create a Run - -- (Kubeflow as a Service) Click on Create Run in the view from the previous step -- Choose the experiment we created in Step 23 -- Input your desired run parameters. For example: -``` -TRIAL = 1 -EPOCHS = 2 -BATCH_SIZE = 64 -EMBED_DIM = 100 -HIDDEN_DIM = 128 -DROPOUT = .2 -SP_DROPOUT = .3 -TRAIN_SEQUENCE_LENGTH = 107 -``` -- Click Start -- Click on the run name to view the runtime execution graph - - - - -![image6](https://user-images.githubusercontent.com/17012391/177002214-8258e3fa-e669-43cc-979d-70c1059f6aae.png) - - - - - - - - - - - - - - - - - - - - -## Troubleshooting Tips: -While running the pipeline as mentioned above you may come across this error: -![kaggle-secret-error-01](https://user-images.githubusercontent.com/17012391/175290593-aac58d80-0d9f-47bd-bd20-46e6f5207210.PNG) - -errorlog: - -``` -kaggle.rest.ApiException: (403) -Reason: Forbidden -HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json', 'Date': 'Thu, 23 Jun 2022 11:31:18 GMT', 'Access-Control-Allow-Credentials': 'true', 'Set-Cookie': 'ka_sessionid=6817a347c75399a531148e19cad0aaeb; max-age=2626560; path=/, GCLB=CIGths3--ebbUg; path=/; HttpOnly', 'Transfer-Encoding': 'chunked', 'Vary': -HTTP response body: b'{"code":403,"message":"You must accept this competition\\u0027s rules before you\\u0027ll be able to download files."}' - -``` -This error occours for two reasons: -- Your Kaggle account is not verified with your phone number. -- Rules for this specific competitions are not accepted. - -Lets accept Rules of competition -![rules](https://user-images.githubusercontent.com/17012391/175306310-10808262-07ce-4952-8fb0-3b7754e9fb46.png) - -Click on "I Understand and Accept". After this you will be prompted to verify your account using your phone number: -![kaggle-secret-error-03](https://user-images.githubusercontent.com/17012391/175291608-daad1a47-119a-4e47-b48b-4f878d65ddd7.PNG) - -Add your phone number and Kaggle will send the code to your number, enter this code and verify your account. ( Note: pipeline wont run if your Kaggle account is not verified ) - -## Success -After the kaggle account is verified pipeline run is successful we will get the following: -Screenshot 2022-06-06 at 3 00 51 PM +# Objective + +This example is based on the Titanic OpenVaccine competition (https://www.kaggle.com/c/stanford-covid-vaccine). The objective of this exercise is to develop models and design rules for RNA degradation. + +## Environment + +This pipeline was tested using Kubeflow 1.4 and kfp 1.1.2 and x86-64 and ARM based system which includes all Intel and AMD based CPU's and M1/M2 series Macbooks. + +## Step 1: Setup Kubeflow as a Service + +- If you haven’t already, sign up (https://www.arrikto.com/kubeflow-as-a-service/) +- Deploy Kubeflow + +## Step 2: Launch a Notebook Server + +- Bump memory to 2GB and vCPUs to 2 + +## Step 3: Clone the Project Repo to Your Notebook + +- (Kubeflow as a Service) Open up a terminal in the Notebook Server and git clone the `kubeflow/examples` repository +``` +git clone https://github.com/kubeflow/examples +``` +## Step 4: Setup DockerHub and Docker + +- If you haven’t already, sign up (https://hub.docker.com/) for DockerHub +- If you haven’t already, install Docker Desktop locally (https://www.docker.com/products/docker-desktop/) OR install the Docker command line utility (https://docs.docker.com/get-docker/) and enter `sudo docker login` command in your terminal and log into Docker with your your DockerHub username and password + + +## Step 5: Setup Kaggle + +- If you haven’t already done so, sign up (https://www.kaggle.com/) for Kaggle +- (On Kaggle) Generate an API token (https://www.kaggle.com/docs/api) +- (Kubeflow as a Service) Create a Kubernetes secret + +``` +kubectl create secret generic kaggle-secret --from-literal=KAGGLE_USERNAME= --from-literal=KAGGLE_KEY= +``` + +## Step 6: Install Git + +- (Locally) If you don’t have it already, install Git (https://github.com/git-guides/install-git) + +## Step 7: Clone the Project Repo Locally + +- (Locally) Git clone the `kubeflow/examples` repository +``` +git clone https://github.com/kubeflow/examples +``` + +## Step 8: Create a PodDefault Resource + +- (Kubeflow as a Service) Navigate to the `openvaccine-kaggle-competition` directory +- Create a `resource.yaml` file + +resource.yaml: +``` +apiVersion: "kubeflow.org/v1alpha1" +kind: PodDefault +metadata: + name: kaggle-access +spec: + selector: + matchLabels: + kaggle-secret: "true" + desc: "kaggle-access" + volumeMounts: + - name: secret-volume + mountPath: /secret/kaggle + volumes: + - name: secret-volume + secret: + secretName: kaggle-secret +``` + +![image2](https://user-images.githubusercontent.com/17012391/177001253-3e525eb6-3415-428c-a52b-11803326af6b.png) + +- Apply created resource using: `kubectl apply -f resource.yaml` + +## Step 9: Explore the `load-data` directory + +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/load-data` directory +- Open up the `load.py` file +- Note the code in this file that will perform the actions required in the “load-data” pipeline step + +image7 + +## Step 10: Build the `load-data` Docker Image + +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/load-data` directory +- Build the Docker image if locally you are using arm64 (Apple M1) + +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` + +## Step 11: Push the `load-data` Docker Image to DockerHub + +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/load-data` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` + +## Step 12: Explore the `preprocess-data` directory + +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/preprocess-data` directory +- Open up the `preprocess.py` file +- Note the code in this file that will perform the actions required in the “preprocess” pipeline step + +image5 + + +## Step 13: Explore the `preprocess-data` directory +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/preprocess-data` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` + +## Step 14: Push the `preprocess-data` Docker Image to DockerHub + +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/preprocess-data` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` + +## Step 15: Explore the `model-training` directory + +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-training` directory +- Open up the `model.py` file +- Note the code in this file that will perform the actions required in the “train” pipeline step + +![image4](https://user-images.githubusercontent.com/17012391/177001740-a63f190c-284e-4328-ba01-17dbdbe61cee.png) + +## Step 16: Build the `model-training` Docker Image + +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-training` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` + +## Step 17: Push the `model-training` Docker Image to DockerHub + +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-training` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` + +## Step 18: Explore the `model-evaluation` directory + +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-evaluation` directory +- Open up the `eval.py` file +- Note the code in this file that will perform the actions required in the “test” pipeline step + +![image1](https://user-images.githubusercontent.com/17012391/177001951-1f7b13b9-adea-48c1-89a7-d8dc67214133.png) + + +## Step 19: Build the `model-evaluation` Docker Image + +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-evaluation` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` + +## Step 20: Push the `model-evaluation` Docker Image to DockerHub + +- (Locally) Navigate to the `openvaccine-kaggle-competition/pipeline-components/model-evaluation` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` +## Step 21: Modify the openvaccine-kaggle-competiton-kfp.py file + +- (Kubeflow as a Service) Navigate to the `openvaccine-kaggle-competition` directory +- Update the `openvaccine-kaggle-competiton-kfp.py` with accurate Docker Image inputs + +``` + return dsl.ContainerOp( + name = 'load-data', + image = '/:', + +—----- + +def GetMsg(comp1): + return dsl.ContainerOp( + name = 'preprocess', + image = '/:', + +—----- + +def Train(comp2, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength): + return dsl.ContainerOp( + name = 'train', + image = '/:', + +—----- + +def Eval(comp1, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength): + return dsl.ContainerOp( + name = 'Evaluate', + image = '/:', +``` + +## Step 22: Generate a KFP Pipeline yaml File + +- (Locally) Navigate to the `openvaccine-kaggle-competition` directory and delete the existing `openvaccine-kaggle-competition-kfp.yaml` file +- (Kubeflow as a Service) Navigate to the openvaccine-kaggle-competition directory + +Build a python virtual environment : + + +Step a) Update pip +``` +python3 -m pip install --upgrade pip +``` + +Step b) Install virtualenv +``` +sudo pip3 install virtualenv +``` + +Step c) Check the installed version of venv +``` +virtualenv --version +``` + +Step d) Name your virtual enviornment as kfp +``` +virtualenv kfp +``` + +Step e) Activate your venv. +``` +source kfp/bin/activate +``` + +After this virtual environment will get activated. Now in our activated venv we need to install following packages: +``` +sudo apt-get update +sudo apt-get upgrade +sudo apt-get install -y git python3-pip + +python3 -m pip install kfp==1.1.2 +``` + +After installing packages create the yaml file + +Inside venv point your terminal to a path which contains our kfp file to build pipeline (openvaccine-kaggle-competition-kfp.py) and run these commands to generate a `yaml` file for the Pipeline: + +``` +python3 openvaccine-kaggle-competition-kfp.py +``` +image3 + +Download the `openvaccine-kaggle-competition-kfp.yaml` file that was created to your local `openvaccine-kaggle-competition` directory + +## Step 23: Create an Experiment + +- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Experiments (KFP) > Create Experiment view +- Name the experiment and click Next +- Click on Experiments (KFP) to view the experiment you just created + +## Step 24: Create a Pipeline + + +- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Pipelines > +Upload Pipeline view +- Name the pipeline +- Click on Upload a file +- Upload the local `openvaccine-kaggle-competition-kfp.yaml` file +- Click Create + +## Step 25: Create a Run + +- (Kubeflow as a Service) Click on Create Run in the view from the previous step +- Choose the experiment we created in Step 23 +- Input your desired run parameters. For example: +``` +TRIAL = 1 +EPOCHS = 2 +BATCH_SIZE = 64 +EMBED_DIM = 100 +HIDDEN_DIM = 128 +DROPOUT = .2 +SP_DROPOUT = .3 +TRAIN_SEQUENCE_LENGTH = 107 +``` +- Click Start +- Click on the run name to view the runtime execution graph + + + + +![image6](https://user-images.githubusercontent.com/17012391/177002214-8258e3fa-e669-43cc-979d-70c1059f6aae.png) + + + + + + + + + + + + + + + + + + + + +## Troubleshooting Tips: +While running the pipeline as mentioned above you may come across this error: +![kaggle-secret-error-01](https://user-images.githubusercontent.com/17012391/175290593-aac58d80-0d9f-47bd-bd20-46e6f5207210.PNG) + +errorlog: + +``` +kaggle.rest.ApiException: (403) +Reason: Forbidden +HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json', 'Date': 'Thu, 23 Jun 2022 11:31:18 GMT', 'Access-Control-Allow-Credentials': 'true', 'Set-Cookie': 'ka_sessionid=6817a347c75399a531148e19cad0aaeb; max-age=2626560; path=/, GCLB=CIGths3--ebbUg; path=/; HttpOnly', 'Transfer-Encoding': 'chunked', 'Vary': +HTTP response body: b'{"code":403,"message":"You must accept this competition\\u0027s rules before you\\u0027ll be able to download files."}' + +``` +This error occours for two reasons: +- Your Kaggle account is not verified with your phone number. +- Rules for this specific competitions are not accepted. + +Lets accept Rules of competition +![rules](https://user-images.githubusercontent.com/17012391/175306310-10808262-07ce-4952-8fb0-3b7754e9fb46.png) + +Click on "I Understand and Accept". After this you will be prompted to verify your account using your phone number: +![kaggle-secret-error-03](https://user-images.githubusercontent.com/17012391/175291608-daad1a47-119a-4e47-b48b-4f878d65ddd7.PNG) + +Add your phone number and Kaggle will send the code to your number, enter this code and verify your account. ( Note: pipeline wont run if your Kaggle account is not verified ) + +## Success +After the kaggle account is verified pipeline run is successful we will get the following: +Screenshot 2022-06-06 at 3 00 51 PM diff --git a/openvaccine-kaggle-competition/openvaccine-kaggle-competition-kfp.py b/openvaccine-kaggle-competition/openvaccine-kaggle-competition-kfp.py index 120859e2c..a79f9f710 100644 --- a/openvaccine-kaggle-competition/openvaccine-kaggle-competition-kfp.py +++ b/openvaccine-kaggle-competition/openvaccine-kaggle-competition-kfp.py @@ -1,81 +1,81 @@ -import kfp -from kfp import dsl - -def SendMsg(): - vop = dsl.VolumeOp(name="pvc", - resource_name="pvc", size='1Gi', - modes=dsl.VOLUME_MODE_RWO) - - return dsl.ContainerOp( - name = 'load-data', - image = 'hubdocker76/openvaccine:v10', - command = ['python3', 'load.py'], - - pvolumes={ - '/data': vop.volume - } - ) - -def GetMsg(comp1): - return dsl.ContainerOp( - name = 'preprocess', - image = 'hubdocker76/preprocess-data:v10', - pvolumes={ - '/data': comp1.pvolumes['/data'] - }, - command = ['python3', 'preprocess.py'] - ) - -def Train(comp2, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength): - return dsl.ContainerOp( - name = 'train', - image = 'hubdocker76/model-training:v21', - command = ['python3', 'model.py'], - arguments=[ - '--LR', trial, - '--EPOCHS', epoch, - '--BATCH_SIZE', batchsize, - '--EMBED_DIM', embeddim, - '--HIDDEN_DIM', hiddendim, - '--DROPOUT', dropout, - '--SP_DROPOUT', spdropout, - '--TRAIN_SEQUENCE_LENGTH', trainsequencelength - ], - pvolumes={ - '/data': comp2.pvolumes['/data'] - } - ) - -def Eval(comp1, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength): - return dsl.ContainerOp( - name = 'Evaluate', - image = 'hubdocker76/eval:v4', - arguments=[ - '--LR', trial, - '--EPOCHS', epoch, - '--BATCH_SIZE', batchsize, - '--EMBED_DIM', embeddim, - '--HIDDEN_DIM', hiddendim, - '--DROPOUT', dropout, - '--SP_DROPOUT', spdropout, - '--TRAIN_SEQUENCE_LENGTH', trainsequencelength - ], - pvolumes={ - '/data': comp1.pvolumes['/data'] - }, - command = ['python3', 'eval.py'] - ) - -@dsl.pipeline( - name = 'openvaccine', - description = 'pipeline to run openvaccine') - -def passing_parameter(trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength): - comp1 = SendMsg().add_pod_label("kaggle-secret", "true") - comp2 = GetMsg(comp1) - comp3 = Train(comp2, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength) - comp4 = Eval(comp3, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength) - -if __name__ == '__main__': - import kfp.compiler as compiler - compiler.Compiler().compile(passing_parameter, __file__[:-3]+ '.yaml') +import kfp +from kfp import dsl + +def SendMsg(): + vop = dsl.VolumeOp(name="pvc", + resource_name="pvc", size='1Gi', + modes=dsl.VOLUME_MODE_RWO) + + return dsl.ContainerOp( + name = 'load-data', + image = 'hubdocker76/openvaccine:v10', + command = ['python3', 'load.py'], + + pvolumes={ + '/data': vop.volume + } + ) + +def GetMsg(comp1): + return dsl.ContainerOp( + name = 'preprocess', + image = 'hubdocker76/preprocess-data:v10', + pvolumes={ + '/data': comp1.pvolumes['/data'] + }, + command = ['python3', 'preprocess.py'] + ) + +def Train(comp2, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength): + return dsl.ContainerOp( + name = 'train', + image = 'hubdocker76/model-training:v21', + command = ['python3', 'model.py'], + arguments=[ + '--LR', trial, + '--EPOCHS', epoch, + '--BATCH_SIZE', batchsize, + '--EMBED_DIM', embeddim, + '--HIDDEN_DIM', hiddendim, + '--DROPOUT', dropout, + '--SP_DROPOUT', spdropout, + '--TRAIN_SEQUENCE_LENGTH', trainsequencelength + ], + pvolumes={ + '/data': comp2.pvolumes['/data'] + } + ) + +def Eval(comp1, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength): + return dsl.ContainerOp( + name = 'Evaluate', + image = 'hubdocker76/eval:v4', + arguments=[ + '--LR', trial, + '--EPOCHS', epoch, + '--BATCH_SIZE', batchsize, + '--EMBED_DIM', embeddim, + '--HIDDEN_DIM', hiddendim, + '--DROPOUT', dropout, + '--SP_DROPOUT', spdropout, + '--TRAIN_SEQUENCE_LENGTH', trainsequencelength + ], + pvolumes={ + '/data': comp1.pvolumes['/data'] + }, + command = ['python3', 'eval.py'] + ) + +@dsl.pipeline( + name = 'openvaccine', + description = 'pipeline to run openvaccine') + +def passing_parameter(trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength): + comp1 = SendMsg().add_pod_label("kaggle-secret", "true") + comp2 = GetMsg(comp1) + comp3 = Train(comp2, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength) + comp4 = Eval(comp3, trial, epoch, batchsize, embeddim, hiddendim, dropout, spdropout, trainsequencelength) + +if __name__ == '__main__': + import kfp.compiler as compiler + compiler.Compiler().compile(passing_parameter, __file__[:-3]+ '.yaml') diff --git a/pipelines-demo/volume/volume_example.py b/pipelines-demo/volume/volume_example.py index 59ac2f1a0..114868bc0 100644 --- a/pipelines-demo/volume/volume_example.py +++ b/pipelines-demo/volume/volume_example.py @@ -1,63 +1,63 @@ -# Copyright 2023 kbthu. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import kfp -from kfp import dsl - -def create_pv(): - return dsl.VolumeOp( - name="create_pv", - resource_name="kfp-pvc", - size="1Gi", - modes=dsl.VOLUME_MODE_RWO - ) - - -def generate_data(vol_name: str): - cop = dsl.ContainerOp( - name='generate_data', - image='bash:5.1', - command=['sh', '-c'], - arguments=['echo $(( $RANDOM % 10 + 1 )) | tee /mnt/out.txt'] - ) - cop.container.set_image_pull_policy('IfNotPresent') - cop.add_pvolumes({'/mnt': dsl.PipelineVolume(pvc=vol_name)}) - return cop - - -def use_pre_data(vol_name: str): - cop = dsl.ContainerOp( - name='use_pre_data', - image='bash:5.1', - command=['sh', '-c'], - arguments=['tail /mnt/out.txt'] - ) - cop.container.set_image_pull_policy('IfNotPresent') - cop.add_pvolumes({'/mnt': dsl.PipelineVolume(pvc=vol_name)}) - return cop - - -@dsl.pipeline( - name="Kubeflow volume example", - description="Demonstrate the use case of volume on Kubeflow pipeline." -) -def volume_example(): - vop = create_pv() - cop = generate_data(vop.outputs["name"]).after(vop) - use_pre_data(vop.outputs["name"]).after(vop,cop) - - -if __name__ == "__main__": - import kfp.compiler as compiler +# Copyright 2023 kbthu. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import kfp +from kfp import dsl + +def create_pv(): + return dsl.VolumeOp( + name="create_pv", + resource_name="kfp-pvc", + size="1Gi", + modes=dsl.VOLUME_MODE_RWO + ) + + +def generate_data(vol_name: str): + cop = dsl.ContainerOp( + name='generate_data', + image='bash:5.1', + command=['sh', '-c'], + arguments=['echo $(( $RANDOM % 10 + 1 )) | tee /mnt/out.txt'] + ) + cop.container.set_image_pull_policy('IfNotPresent') + cop.add_pvolumes({'/mnt': dsl.PipelineVolume(pvc=vol_name)}) + return cop + + +def use_pre_data(vol_name: str): + cop = dsl.ContainerOp( + name='use_pre_data', + image='bash:5.1', + command=['sh', '-c'], + arguments=['tail /mnt/out.txt'] + ) + cop.container.set_image_pull_policy('IfNotPresent') + cop.add_pvolumes({'/mnt': dsl.PipelineVolume(pvc=vol_name)}) + return cop + + +@dsl.pipeline( + name="Kubeflow volume example", + description="Demonstrate the use case of volume on Kubeflow pipeline." +) +def volume_example(): + vop = create_pv() + cop = generate_data(vop.outputs["name"]).after(vop) + use_pre_data(vop.outputs["name"]).after(vop,cop) + + +if __name__ == "__main__": + import kfp.compiler as compiler compiler.Compiler().compile(volume_example, __file__ + ".yaml") \ No newline at end of file diff --git a/pipelines/azurepipeline/code/deploy/Dockerfile b/pipelines/azurepipeline/code/deploy/Dockerfile old mode 100755 new mode 100644 diff --git a/pipelines/azurepipeline/code/deploy/score.py b/pipelines/azurepipeline/code/deploy/score.py old mode 100755 new mode 100644 diff --git a/pipelines/azurepipeline/code/preprocess/Dockerfile b/pipelines/azurepipeline/code/preprocess/Dockerfile old mode 100755 new mode 100644 diff --git a/pipelines/azurepipeline/code/preprocess/data.py b/pipelines/azurepipeline/code/preprocess/data.py old mode 100755 new mode 100644 diff --git a/pipelines/azurepipeline/code/register/Dockerfile b/pipelines/azurepipeline/code/register/Dockerfile old mode 100755 new mode 100644 diff --git a/pipelines/azurepipeline/code/register/register.py b/pipelines/azurepipeline/code/register/register.py old mode 100755 new mode 100644 diff --git a/pipelines/azurepipeline/code/training/Dockerfile b/pipelines/azurepipeline/code/training/Dockerfile old mode 100755 new mode 100644 diff --git a/pipelines/azurepipeline/code/training/train.py b/pipelines/azurepipeline/code/training/train.py old mode 100755 new mode 100644 diff --git a/pipelines/mnist-pipelines/deploy-service/src/deploy.sh b/pipelines/mnist-pipelines/deploy-service/src/deploy.sh old mode 100755 new mode 100644 diff --git a/pipelines/simple-notebook-pipeline/README.md b/pipelines/simple-notebook-pipeline/README.md index 3174b84a1..6e562e1a8 100644 --- a/pipelines/simple-notebook-pipeline/README.md +++ b/pipelines/simple-notebook-pipeline/README.md @@ -1,10 +1,10 @@ -# Simple Notebook Pipeline on GCP -This notebook shows how to compile and run a simple Kubeflow pipeline using Jupyter notebooks and Google Cloud Storage. The pipeline is very simple, and is a helpful starting point for people new to Kubeflow. - -## Setup - -### Setup notebook server -This pipeline requires you to [setup a notebook server](https://www.kubeflow.org/docs/components/notebooks/setup/) in the Kubeflow UI. After you are setup, upload this notebook and then run it in the notebook server. - -### Upload the notebook to the Kubeflow UI -In order to run this pipeline, make sure to upload the notebook to your notebook server in the Kubeflow UI. You can clone this repo in the Jupyter notebook server by connecting to the notebook server and then selecting New > Terminal. In the terminal type `git clone https://github.com/kubeflow/examples.git`. +# Simple Notebook Pipeline on GCP +This notebook shows how to compile and run a simple Kubeflow pipeline using Jupyter notebooks and Google Cloud Storage. The pipeline is very simple, and is a helpful starting point for people new to Kubeflow. + +## Setup + +### Setup notebook server +This pipeline requires you to [setup a notebook server](https://www.kubeflow.org/docs/components/notebooks/setup/) in the Kubeflow UI. After you are setup, upload this notebook and then run it in the notebook server. + +### Upload the notebook to the Kubeflow UI +In order to run this pipeline, make sure to upload the notebook to your notebook server in the Kubeflow UI. You can clone this repo in the Jupyter notebook server by connecting to the notebook server and then selecting New > Terminal. In the terminal type `git clone https://github.com/kubeflow/examples.git`. diff --git a/pytorch_mnist/Makefile b/pytorch_mnist/Makefile old mode 100755 new mode 100644 diff --git a/pytorch_mnist/serving/seldon-wrapper/build_image.sh b/pytorch_mnist/serving/seldon-wrapper/build_image.sh old mode 100755 new mode 100644 diff --git a/pytorch_mnist/training/ddp/mnist/Dockerfile.traingpu b/pytorch_mnist/training/ddp/mnist/Dockerfile.traingpu old mode 100755 new mode 100644 diff --git a/pytorch_mnist/training/ddp/mnist/build_image.sh b/pytorch_mnist/training/ddp/mnist/build_image.sh old mode 100755 new mode 100644 diff --git a/pytorch_mnist/training/ddp/mnist/mnist_DDP.py b/pytorch_mnist/training/ddp/mnist/mnist_DDP.py old mode 100755 new mode 100644 diff --git a/pytorch_mnist/web-ui/build_image.sh b/pytorch_mnist/web-ui/build_image.sh old mode 100755 new mode 100644 diff --git a/telco-customer-churn-kaggle-competition/images/... b/telco-customer-churn-kaggle-competition/images/... deleted file mode 100644 index 8b1378917..000000000 --- a/telco-customer-churn-kaggle-competition/images/... +++ /dev/null @@ -1 +0,0 @@ - diff --git a/telco-customer-churn-kaggle-competition/requirements.txt b/telco-customer-churn-kaggle-competition/requirements.txt index c1db402e5..b7c9aa304 100644 --- a/telco-customer-churn-kaggle-competition/requirements.txt +++ b/telco-customer-churn-kaggle-competition/requirements.txt @@ -1,6 +1,6 @@ -pandas -seaborn -lightgbm -catboost -xgboost -wget +pandas +seaborn +lightgbm +catboost +xgboost +wget diff --git a/tensorflow_cuj/text_classification/distributed_text_classification_rnn.py b/tensorflow_cuj/text_classification/distributed_text_classification_rnn.py old mode 100755 new mode 100644 diff --git a/test/copy_secret.sh b/test/copy_secret.sh old mode 100755 new mode 100644 diff --git a/titanic-kaggle-competition/Readme.md b/titanic-kaggle-competition/Readme.md index 5176c0bd8..7137292e2 100644 --- a/titanic-kaggle-competition/Readme.md +++ b/titanic-kaggle-competition/Readme.md @@ -1,464 +1,464 @@ -# Objective - -This example is based on the Titanic Kaggle competition (https://www.kaggle.com/c/titanic). The objective of this exercise is to use machine learning to create a model that predicts which passengers survived the Titanic shipwreck. - -## Environment - -This pipeline was tested using Kubeflow 1.4 and kfp 1.1.2 and x86-64 and ARM based system which includes all Intel and AMD based CPU's and M1/M2 series Macbooks - -## Step 1: Setup Kubeflow as a Service - -- If you haven’t already, sign up (https://www.arrikto.com/kubeflow-as-a-service/) -- Deploy Kubeflow - -## Step 2: Launch a Notebook Server - -- Default should work - -## Step 3: Clone the Project Repo to Your Notebook - -- (Kubeflow as a Service) Open up a terminal in the Notebook Server and git clone the `kubeflow/examples` repository -``` -git clone https://github.com/kubeflow/examples -``` - -## Step 4: Setup DockerHub and Docker - -- If you haven’t already, sign up (https://hub.docker.com/) for DockerHub -- If you haven’t already, install Docker Desktop (https://www.docker.com/products/docker-desktop/) locally OR install the Docker command line utility (https://docs.docker.com/get-docker/) and enter `sudo docker login` command in your terminal and log into Docker with your your DockerHub username and password - -## Step 5: Setup Kaggle - -- If you haven’t already done so, sign up (https://www.kaggle.com/) for Kaggle -- (On Kaggle) Generate an API token (https://www.kaggle.com/docs/api) -- (Kubeflow as a Service) Create a Kubernetes secret -``` -kubectl create secret generic kaggle-secret --from-literal=KAGGLE_USERNAME= --from-literal=KAGGLE_KEY= -``` - -## Step 6: Install Git - -- (Locally) If you don’t have it already, install Git - -## Step 7: Clone the Project Repo Locally - -- (Locally) Git clone the kubeflow/examples repository -``` -git clone https://github.com/kubeflow/examples -``` -## Step 8: Create a `PodDefault` Resource - -- (Kubeflow as a Service) Navigate to the `titanic-kaggle-competition` directory -- Create a `resource.yaml` file - -resource.yaml: -``` -apiVersion: "kubeflow.org/v1alpha1" -kind: PodDefault -metadata: - name: kaggle-access -spec: - selector: - matchLabels: - kaggle-secret: "true" - desc: "kaggle-access" - volumeMounts: - - name: secret-volume - mountPath: /secret/kaggle - volumes: - - name: secret-volume - secret: - secretName: kaggle-secret -``` -Screenshot 2022-07-04 at 4 56 41 PM - -- Apply the resource.yaml file: `kubectl apply -f resource.yaml` - -## Step 9: Explore the pre-process directory - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/pre-process` directory -- Open up the `preprocess.py` file -- Note the code in this file that will perform the actions required in the “preprocess-data” pipeline step - -Screenshot 2022-07-04 at 5 00 01 PM - -## Step 10: Build the preprocess-data Docker Image - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/pre-process` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` -## Step 11: Push the preprocess-data Docker Image to DockerHub - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/load-data` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` -## Step 12: Explore the featureengineering directory - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/featureengineering` directory -- Open up the `featureengg.py` file -- Note the code in this file that will perform the actions required in the “featureengineering” pipeline step - -Screenshot 2022-07-04 at 5 02 50 PM - -## Step 13: Build the featureengineering Docker Image - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/featureengineering` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` -## Step 14: Push the featureengineering Docker Image to DockerHub - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/featureengineering` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` - -## Step 15: Explore the decisiontree directory - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/decisiontree` directory -- Open up the `decisiontree.py` file -- Note the code in this file that will perform the actions required in the “decision-tree” pipeline step - -Screenshot 2022-07-04 at 5 05 43 PM - -## Step 16: Build the decisiontree Docker Image - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/decisiontree` directory -Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` - -## Step 17: Push the decisiontree Docker Image to DockerHub - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/decisiontree` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` -## Step 18: Explore the logisticregression directory - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/logisticregression` directory -- Open up the `regression.py` file -- Note the code in this file that will perform the actions required in the “regression” pipeline step - -Screenshot 2022-07-04 at 5 08 11 PM - -## Step 19: Build the regression Docker Image - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/logisticregression` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` -## Step 20: Push the regression Docker Image to DockerHub - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/logisticregression` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` -## Step 21: Explore the naivebayes directory - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/naivebayes` directory -- Open up the `naivebayes.py` file -Note the code in this file that will perform the actions required in the “bayes” pipeline step -Screenshot 2022-07-04 at 5 10 36 PM - -## Step 22: Build the naivebayes Docker Image - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/naivebayes` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` -## Step 23: Push the naivebayes Docker Image to DockerHub - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/naivebayes` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` -## Step 24: Explore the randomforest directory - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/randomforest` directory -- Open up the `randomforest.py` file -- Note the code in this file that will perform the actions required in the “random-forest” pipeline step - - -Screenshot 2022-07-04 at 5 12 54 PM - -## Step 25: Build the random-forest Docker Image - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/randomforest` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` - -## Step 26: Push the random-forest Docker Image to DockerHub - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/randomforest` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` -## Step 27: Explore the svm directory - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/svm` directory -- Open up the `svm.py` file -- Note the code in this file that will perform the actions required in the “svm” pipeline step - -Screenshot 2022-07-04 at 5 15 23 PM - -## Step 28: Build the svm Docker Image - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/svm` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` -## Step 29: Push the svm Docker Image to DockerHub - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/svm` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` -## Step 30: Explore the results directory - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/results` directory -- Open up the `result.py` file -- Note the code in this file that will perform the actions required in the “results” pipeline step - -Screenshot 2022-07-04 at 5 18 34 PM - -## Step 31: Build the results Docker Image - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/results` directory -- Build the Docker image if locally you are using arm64 (Apple M1) -``` -docker build --platform=linux/amd64 -t /:-amd64 . -``` -- OR build the Docker image if locally you are using amd64 -``` -docker build -t /: . -``` - -## Step 32: Push the results Docker Image to DockerHub - -- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/results` directory -- Push the Docker image if locally you are using arm64 (Apple M1) -``` -docker push /:-amd64 -``` -- OR build the Docker image if locally you are using amd64 -``` -docker push /: -``` - -## Step 33: Modify the titanic-kfp.py file - -- (Kubeflow as a Service) Navigate to the `titanic-kaggle-competition` directory -- Update the `titanic-kfp.py` with accurate Docker Image inputs -``` - return dsl.ContainerOp( - name = 'Preprocess Data', - image = '/:', - -—----- - - return dsl.ContainerOp( - name='featureengineering', - image = '/:', - -—----- - - return dsl.ContainerOp( - name='regression', - image = '/:', - -—----- - - return dsl.ContainerOp( - name='bayes', - image = '/:', - -—----- - - return dsl.ContainerOp( - name='random_forest', - image = '/:', - -—----- - - return dsl.ContainerOp( - name='decision_tree', - image = '/:', - -—----- - - return dsl.ContainerOp( - name='svm', - image = '/:', - -—----- - - return dsl.ContainerOp( - name='results', - image = '/:', -``` - -## Step 34: Generate a KFP Pipeline yaml File - -- (Kubeflow as a Service) Navigate to the `titanic-kaggle-competition` directory -Build a python virtual environment: - -Step a) Update pip -``` -python3 -m pip install --upgrade pip -``` - -Step b) Install virtualenv -``` -sudo pip3 install virtualenv -``` - -Step c) Check the installed version of venv -``` -virtualenv --version -``` - -Step d) Name your virtual enviornment as kfp -``` -virtualenv kfp -``` - -Step e) Activate your venv. -``` -source kfp/bin/activate -``` - -After this virtual environment will get activated. Now in our activated venv we need to install following packages: -``` -sudo apt-get update -sudo apt-get upgrade -sudo apt-get install -y git python3-pip - -python3 -m pip install kfp==1.1.2 -``` - -After installing packages create the yaml file -``` -python3 titanic-kaggle-competition-kfp.py -``` - -Screenshot 2022-07-04 at 5 27 37 PM - - -Download the `titanic-kaggle-competition-kfp.yaml` file that was created to your local `titanic-kaggle-competition` directory. - -## Step 35: Create an Experiment - -- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Experiments (KFP) > Create Experiment view -- Name the experiment and click Next -- Click on Experiments (KFP) to view the experiment you just created - -## Step 36: Create a Pipeline - -- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Pipelines > +Upload Pipeline view -- Name the pipeline -- Click on Upload a file -- Upload the local `titanic-kaggle-competition-kfp.yaml` file -- Click Create - - -## Step 37: Create a Run - -- (Kubeflow as a Service) Click on Create Run in the view from the previous step -- Choose the experiment we created in Step 35 -- Click Start -- Click on the run name to view the runtime execution graph - - -![image10](https://user-images.githubusercontent.com/17012391/177150882-3c8abf80-2d6e-4467-9b11-7824d3909e35.png) - - -## Troubleshooting Tips: -While running the pipeline as mentioned above you may come across this error: -errorlog: - -``` -kaggle.rest.ApiException: (403) -Reason: Forbidden -HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json', 'Date': 'Thu, 23 Jun 2022 11:31:18 GMT', 'Access-Control-Allow-Credentials': 'true', 'Set-Cookie': 'ka_sessionid=6817a347c75399a531148e19cad0aaeb; max-age=2626560; path=/, GCLB=CIGths3--ebbUg; path=/; HttpOnly', 'Transfer-Encoding': 'chunked', 'Vary': -HTTP response body: b'{"code":403,"message":"You must accept this competition\\u0027s rules before you\\u0027ll be able to download files."}' - -``` -This error occours for two reasons: -- Your Kaggle account is not verified with your phone number. -- Rules for this specific competitions are not accepted. - -A solution to this is please verify your Kaggle account using your phone number and accept the rules for this specific competition, untill these two steps are satisfied pipeline wont accquire data from Kaggle API and it wont run. +# Objective + +This example is based on the Titanic Kaggle competition (https://www.kaggle.com/c/titanic). The objective of this exercise is to use machine learning to create a model that predicts which passengers survived the Titanic shipwreck. + +## Environment + +This pipeline was tested using Kubeflow 1.4 and kfp 1.1.2 and x86-64 and ARM based system which includes all Intel and AMD based CPU's and M1/M2 series Macbooks + +## Step 1: Setup Kubeflow as a Service + +- If you haven’t already, sign up (https://www.arrikto.com/kubeflow-as-a-service/) +- Deploy Kubeflow + +## Step 2: Launch a Notebook Server + +- Default should work + +## Step 3: Clone the Project Repo to Your Notebook + +- (Kubeflow as a Service) Open up a terminal in the Notebook Server and git clone the `kubeflow/examples` repository +``` +git clone https://github.com/kubeflow/examples +``` + +## Step 4: Setup DockerHub and Docker + +- If you haven’t already, sign up (https://hub.docker.com/) for DockerHub +- If you haven’t already, install Docker Desktop (https://www.docker.com/products/docker-desktop/) locally OR install the Docker command line utility (https://docs.docker.com/get-docker/) and enter `sudo docker login` command in your terminal and log into Docker with your your DockerHub username and password + +## Step 5: Setup Kaggle + +- If you haven’t already done so, sign up (https://www.kaggle.com/) for Kaggle +- (On Kaggle) Generate an API token (https://www.kaggle.com/docs/api) +- (Kubeflow as a Service) Create a Kubernetes secret +``` +kubectl create secret generic kaggle-secret --from-literal=KAGGLE_USERNAME= --from-literal=KAGGLE_KEY= +``` + +## Step 6: Install Git + +- (Locally) If you don’t have it already, install Git + +## Step 7: Clone the Project Repo Locally + +- (Locally) Git clone the kubeflow/examples repository +``` +git clone https://github.com/kubeflow/examples +``` +## Step 8: Create a `PodDefault` Resource + +- (Kubeflow as a Service) Navigate to the `titanic-kaggle-competition` directory +- Create a `resource.yaml` file + +resource.yaml: +``` +apiVersion: "kubeflow.org/v1alpha1" +kind: PodDefault +metadata: + name: kaggle-access +spec: + selector: + matchLabels: + kaggle-secret: "true" + desc: "kaggle-access" + volumeMounts: + - name: secret-volume + mountPath: /secret/kaggle + volumes: + - name: secret-volume + secret: + secretName: kaggle-secret +``` +Screenshot 2022-07-04 at 4 56 41 PM + +- Apply the resource.yaml file: `kubectl apply -f resource.yaml` + +## Step 9: Explore the pre-process directory + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/pre-process` directory +- Open up the `preprocess.py` file +- Note the code in this file that will perform the actions required in the “preprocess-data” pipeline step + +Screenshot 2022-07-04 at 5 00 01 PM + +## Step 10: Build the preprocess-data Docker Image + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/pre-process` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` +## Step 11: Push the preprocess-data Docker Image to DockerHub + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/load-data` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` +## Step 12: Explore the featureengineering directory + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/featureengineering` directory +- Open up the `featureengg.py` file +- Note the code in this file that will perform the actions required in the “featureengineering” pipeline step + +Screenshot 2022-07-04 at 5 02 50 PM + +## Step 13: Build the featureengineering Docker Image + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/featureengineering` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` +## Step 14: Push the featureengineering Docker Image to DockerHub + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/featureengineering` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` + +## Step 15: Explore the decisiontree directory + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/decisiontree` directory +- Open up the `decisiontree.py` file +- Note the code in this file that will perform the actions required in the “decision-tree” pipeline step + +Screenshot 2022-07-04 at 5 05 43 PM + +## Step 16: Build the decisiontree Docker Image + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/decisiontree` directory +Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` + +## Step 17: Push the decisiontree Docker Image to DockerHub + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/decisiontree` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` +## Step 18: Explore the logisticregression directory + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/logisticregression` directory +- Open up the `regression.py` file +- Note the code in this file that will perform the actions required in the “regression” pipeline step + +Screenshot 2022-07-04 at 5 08 11 PM + +## Step 19: Build the regression Docker Image + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/logisticregression` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` +## Step 20: Push the regression Docker Image to DockerHub + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/logisticregression` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` +## Step 21: Explore the naivebayes directory + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/naivebayes` directory +- Open up the `naivebayes.py` file +Note the code in this file that will perform the actions required in the “bayes” pipeline step +Screenshot 2022-07-04 at 5 10 36 PM + +## Step 22: Build the naivebayes Docker Image + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/naivebayes` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` +## Step 23: Push the naivebayes Docker Image to DockerHub + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/naivebayes` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` +## Step 24: Explore the randomforest directory + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/randomforest` directory +- Open up the `randomforest.py` file +- Note the code in this file that will perform the actions required in the “random-forest” pipeline step + + +Screenshot 2022-07-04 at 5 12 54 PM + +## Step 25: Build the random-forest Docker Image + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/randomforest` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` + +## Step 26: Push the random-forest Docker Image to DockerHub + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/randomforest` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` +## Step 27: Explore the svm directory + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/svm` directory +- Open up the `svm.py` file +- Note the code in this file that will perform the actions required in the “svm” pipeline step + +Screenshot 2022-07-04 at 5 15 23 PM + +## Step 28: Build the svm Docker Image + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/svm` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` +## Step 29: Push the svm Docker Image to DockerHub + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/svm` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` +## Step 30: Explore the results directory + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/results` directory +- Open up the `result.py` file +- Note the code in this file that will perform the actions required in the “results” pipeline step + +Screenshot 2022-07-04 at 5 18 34 PM + +## Step 31: Build the results Docker Image + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/results` directory +- Build the Docker image if locally you are using arm64 (Apple M1) +``` +docker build --platform=linux/amd64 -t /:-amd64 . +``` +- OR build the Docker image if locally you are using amd64 +``` +docker build -t /: . +``` + +## Step 32: Push the results Docker Image to DockerHub + +- (Locally) Navigate to the `titanic-kaggle-competition/pipeline-components/results` directory +- Push the Docker image if locally you are using arm64 (Apple M1) +``` +docker push /:-amd64 +``` +- OR build the Docker image if locally you are using amd64 +``` +docker push /: +``` + +## Step 33: Modify the titanic-kfp.py file + +- (Kubeflow as a Service) Navigate to the `titanic-kaggle-competition` directory +- Update the `titanic-kfp.py` with accurate Docker Image inputs +``` + return dsl.ContainerOp( + name = 'Preprocess Data', + image = '/:', + +—----- + + return dsl.ContainerOp( + name='featureengineering', + image = '/:', + +—----- + + return dsl.ContainerOp( + name='regression', + image = '/:', + +—----- + + return dsl.ContainerOp( + name='bayes', + image = '/:', + +—----- + + return dsl.ContainerOp( + name='random_forest', + image = '/:', + +—----- + + return dsl.ContainerOp( + name='decision_tree', + image = '/:', + +—----- + + return dsl.ContainerOp( + name='svm', + image = '/:', + +—----- + + return dsl.ContainerOp( + name='results', + image = '/:', +``` + +## Step 34: Generate a KFP Pipeline yaml File + +- (Kubeflow as a Service) Navigate to the `titanic-kaggle-competition` directory +Build a python virtual environment: + +Step a) Update pip +``` +python3 -m pip install --upgrade pip +``` + +Step b) Install virtualenv +``` +sudo pip3 install virtualenv +``` + +Step c) Check the installed version of venv +``` +virtualenv --version +``` + +Step d) Name your virtual enviornment as kfp +``` +virtualenv kfp +``` + +Step e) Activate your venv. +``` +source kfp/bin/activate +``` + +After this virtual environment will get activated. Now in our activated venv we need to install following packages: +``` +sudo apt-get update +sudo apt-get upgrade +sudo apt-get install -y git python3-pip + +python3 -m pip install kfp==1.1.2 +``` + +After installing packages create the yaml file +``` +python3 titanic-kaggle-competition-kfp.py +``` + +Screenshot 2022-07-04 at 5 27 37 PM + + +Download the `titanic-kaggle-competition-kfp.yaml` file that was created to your local `titanic-kaggle-competition` directory. + +## Step 35: Create an Experiment + +- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Experiments (KFP) > Create Experiment view +- Name the experiment and click Next +- Click on Experiments (KFP) to view the experiment you just created + +## Step 36: Create a Pipeline + +- (Kubeflow as a Service) Within the Kubeflow Central Dashboard, navigate to the Pipelines > +Upload Pipeline view +- Name the pipeline +- Click on Upload a file +- Upload the local `titanic-kaggle-competition-kfp.yaml` file +- Click Create + + +## Step 37: Create a Run + +- (Kubeflow as a Service) Click on Create Run in the view from the previous step +- Choose the experiment we created in Step 35 +- Click Start +- Click on the run name to view the runtime execution graph + + +![image10](https://user-images.githubusercontent.com/17012391/177150882-3c8abf80-2d6e-4467-9b11-7824d3909e35.png) + + +## Troubleshooting Tips: +While running the pipeline as mentioned above you may come across this error: +errorlog: + +``` +kaggle.rest.ApiException: (403) +Reason: Forbidden +HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json', 'Date': 'Thu, 23 Jun 2022 11:31:18 GMT', 'Access-Control-Allow-Credentials': 'true', 'Set-Cookie': 'ka_sessionid=6817a347c75399a531148e19cad0aaeb; max-age=2626560; path=/, GCLB=CIGths3--ebbUg; path=/; HttpOnly', 'Transfer-Encoding': 'chunked', 'Vary': +HTTP response body: b'{"code":403,"message":"You must accept this competition\\u0027s rules before you\\u0027ll be able to download files."}' + +``` +This error occours for two reasons: +- Your Kaggle account is not verified with your phone number. +- Rules for this specific competitions are not accepted. + +A solution to this is please verify your Kaggle account using your phone number and accept the rules for this specific competition, untill these two steps are satisfied pipeline wont accquire data from Kaggle API and it wont run.